gpt4 book ai didi

c# - unity raycast,on raycast leave,怎么办? C#

转载 作者:太空宇宙 更新时间:2023-11-03 23:47:58 25 4
gpt4 key购买 nike

我在理解如何保持对先前被光线转换击中的对象的引用时遇到问题。

例如,我可以将光线转换脚本放在我的第一人称 Controller 的相机上,从相机位置到前向向量*一些值

此脚本附在相机上

public class raycast : MonoBehaviour {
float lenthRay = 10.0f;
Vector3 originePos;
Vector3 dir;
RaycastHit hitinfo;
GameObject hitten;
bool isHitting;
Color beforC;
int selectionLayer = 9;

void Update () {
originePos = Camera.main.transform.position;
dir = Camera.main.transform.forward * lenthRay;
Debug.DrawRay(originePos, dir, Color.blue);

if (Physics.Raycast(originePos, dir, out hitinfo, lenthRay , selectionLayer)) {
hitten = hitinfo.transform.gameObject;
MeshRenderer tmp = hitten.transform.GetComponent<MeshRenderer> ();
beforC = tmp.material.color;
tmp.material.color = Color.black;
}
//hitten.transform.GetComponent<MeshRenderer> ().material.color = beforC;
print(hitten.name);
}

它运行良好,除非我尝试在我的 if 条件之外访问 GameObject Hitten(例如打印 print(hitten.name))

我在从右层击中对象之前收到此错误:

NullReferenceException: Object reference not set to an instance of an object
raycast.Update () (at Assets/raycast.cs:30)

然后当我击中物体时就可以了

但问题是,我不明白如何将对象颜色更改回其原始颜色 (beforC) 后将其转换为 Color.black 当射线退出对象

这就是我在注释行中尝试做的,但我得到的错误与打印的错误相同,而且没有任何东西变黑。

我已经试过了:

originePos = Camera.main.transform.position;
dir = Camera.main.transform.forward * lenthRay;
Debug.DrawRay(originePos, dir, Color.blue);
isHitting = Physics.Raycast (originePos, dir, out hitinfo, lenthRay, selectionLayer);
if (isHitting) {
hitten = hitinfo.transform.gameObject;
MeshRenderer tmp = hitten.transform.GetComponent<MeshRenderer> ();
beforC = tmp.material.color;
tmp.material.color = Color.black;

}
if(!isHitting){
hitten.transform.GetComponent<MeshRenderer> ().material.color = beforC;
print(hitten.name);
}

但是还是不行

你能帮我理解我应该使用的逻辑吗提前致谢

最佳答案

当我试图检测墙壁何时阻挡播放器时,我也有同样的需求。我以前从未使用过 Raycast(或 Linecast),并且很惊讶没有内置方法来检测“进入”、“停留”和“离开”事件。

所以我创建了这个简单的类来为我处理细节。我没有费心创建任何类构造函数,只是将属性公开为公共(public)。它同时处理 Raycasts 和 Linecasts。

一旦您使用属性设置该类,它就会在每一帧为您跟踪您的对象。

下面是一些演示潜在用法的示例代码(我用于墙壁检测的代码):

private RayCaster wallRay;

void Start() {
wallRay = new RayCaster();
wallRay.OnRayEnter += WallRay_OnEnter;
wallRay.OnRayExit += WallRay_OnExit;
wallRay.LayerMask = RayCaster.GetLayerMask("Wall");
wallRay.StartTransform = camera.transform;
wallRay.EndTransform = PlayerManager.Player.transform;
}

void Update() {
wallRay.CastLine();
}

void WallRay_OnEnter(Collider collider) {
// Fade OUT wall section [Needs DOTween (free) installed]
collider.gameObject.renderer.material.DOFade(0.65f, 0.2f);
}

void WallRay_OnExit(Collider collider) {
// Fade IN wall section
collider.gameObject.renderer.material.DOFade(1f, 0.2f);
}

这是 RayCaster 类:

using System;
using System.Collections;
using UnityEngine;

public class RayCaster {

public Transform StartTransform;
public Transform EndTransform;
public Vector3 Direction;
public float RayLength;
public int LayerMask = 0;

public event Action<Collider> OnRayEnter;
public event Action<Collider> OnRayStay;
public event Action<Collider> OnRayExit;

Collider previous;
RaycastHit hit = new RaycastHit();

public bool CastRay() {
Physics.Raycast(StartTransform.position, Direction, out hit, RayLength, LayerMask);
ProcessCollision(hit.collider);
return hit.collider != null ? true : false;
}

public bool CastLine() {
Physics.Linecast(StartTransform.position, EndTransform.position, out hit, LayerMask);
ProcessCollision(hit.collider);
return hit.collider != null ? true : false;
}

private void ProcessCollision(Collider current) {
// No collision this frame.
if (current == null) {
// But there was an object hit last frame.
if (previous != null) {
DoEvent(OnRayExit, previous);
}
}

// The object is the same as last frame.
else if (previous == current) {
DoEvent(OnRayStay, current);
}

// The object is different than last frame.
else if (previous != null) {
DoEvent(OnRayExit, previous);
DoEvent(OnRayEnter, current);
}

// There was no object hit last frame.
else {
DoEvent(OnRayEnter, current);
}

// Remember this object for comparing with next frame.
previous = current;
}


private void DoEvent(Action<Collider> action, Collider collider) {
if (action != null) {
action(collider);
}
}

public static int GetLayerMask(string layerName, int existingMask=0) {
int layer = LayerMask.NameToLayer(layerName);
return existingMask | (1 << layer);
}

}

关于c# - unity raycast,on raycast leave,怎么办? C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26957613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com