不再看时停止勾勒对象?
Stop outlining object when no longer looking at it?
我正在尝试制作一个拾取系统,我认为在您查看它时在它周围画一个轮廓会很酷。我面临的问题是当您不再查看我需要禁用轮廓的对象时。我最终做了一个奇怪的解决方案,并希望得到一些帮助来改进它。
public class PlayerCamera : MonoBehaviour
{
public Transform playerBody;
public Transform cameraHolder;
public float sensitivity;
public float currentY;
void Update()
{
MoveCamera();
LookingAtObject();
}
Outline objectOutline;
void LookingAtObject()
{
if(Physics.Raycast(cameraHolder.transform.position, cameraHolder.transform.forward, out var hit, Mathf.Infinity))
{
var obj = hit.collider.gameObject;
var outline = obj.GetComponent<Outline>();
if (obj && outline)
{
objectOutline = hit.transform.GetComponent<Outline>();
if (objectOutline)
objectOutline.OutlineWidth = 7;
}
else if (objectOutline)
objectOutline.OutlineWidth = 0;
}
}
}
您可以将轮廓对象存储在变量中,每当您击中不同的轮廓对象或什么也没击中时,将轮廓设置回零。
Outline objectOutline;
void LookingAtObject()
{
if (Physics.Raycast(...))
{
var outline = hit.collider.GetComponent<Outline>();
// Make sure the hit object is not the same one we already outlined
//
if (outline != objectOutline)
{
// Remove the outline from our previously viewed object
//
if (objectOutline != null)
{
objectOutline.OutlineWidth = 0;
}
// Store the new outline object
//
objectOutline = outline;
// Since outline could be null, we need to check null before outlining
//
if (objectOutline != null)
{
objectOutline.OutlineWidth = 7;
}
}
}
// If we have an object we outlined and we didnt hit anything,
// remove the outline and reset the variable
//
else if (objectOutline != null)
{
objectOutline.OutlineWidth = 0;
objectOutline = null;
}
}
你需要两个事件来解决这个问题。输入帧和光线输出帧。此代码通过记录前一个 raycastHit
帧并将其与当前命中进行比较来检测哪个 raycast
事件,并相应地设置轮廓。
private RaycastHit lastHit;
void Update()
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(ray, out var hit);
//Physics.Raycast(cameraHolder.transform.position, cameraHolder.transform.forward, out var hit, Mathf.Infinity);
if (hit.transform != lastHit.transform)
{
if (hit.transform) // when raycast Begin
{
var outline = hit.transform.GetComponent<Outline>();
outline.OutlineWidth = 7;
}
else if (lastHit.transform) // when raycast out
{
var outline = lastHit.transform.GetComponent<Outline>();
outline.OutlineWidth = 0;
}
}
lastHit = hit;
}
Hint: I commented on your raycast code for testing. If you want to change the raycast code as before.
我正在尝试制作一个拾取系统,我认为在您查看它时在它周围画一个轮廓会很酷。我面临的问题是当您不再查看我需要禁用轮廓的对象时。我最终做了一个奇怪的解决方案,并希望得到一些帮助来改进它。
public class PlayerCamera : MonoBehaviour
{
public Transform playerBody;
public Transform cameraHolder;
public float sensitivity;
public float currentY;
void Update()
{
MoveCamera();
LookingAtObject();
}
Outline objectOutline;
void LookingAtObject()
{
if(Physics.Raycast(cameraHolder.transform.position, cameraHolder.transform.forward, out var hit, Mathf.Infinity))
{
var obj = hit.collider.gameObject;
var outline = obj.GetComponent<Outline>();
if (obj && outline)
{
objectOutline = hit.transform.GetComponent<Outline>();
if (objectOutline)
objectOutline.OutlineWidth = 7;
}
else if (objectOutline)
objectOutline.OutlineWidth = 0;
}
}
}
您可以将轮廓对象存储在变量中,每当您击中不同的轮廓对象或什么也没击中时,将轮廓设置回零。
Outline objectOutline;
void LookingAtObject()
{
if (Physics.Raycast(...))
{
var outline = hit.collider.GetComponent<Outline>();
// Make sure the hit object is not the same one we already outlined
//
if (outline != objectOutline)
{
// Remove the outline from our previously viewed object
//
if (objectOutline != null)
{
objectOutline.OutlineWidth = 0;
}
// Store the new outline object
//
objectOutline = outline;
// Since outline could be null, we need to check null before outlining
//
if (objectOutline != null)
{
objectOutline.OutlineWidth = 7;
}
}
}
// If we have an object we outlined and we didnt hit anything,
// remove the outline and reset the variable
//
else if (objectOutline != null)
{
objectOutline.OutlineWidth = 0;
objectOutline = null;
}
}
你需要两个事件来解决这个问题。输入帧和光线输出帧。此代码通过记录前一个 raycastHit
帧并将其与当前命中进行比较来检测哪个 raycast
事件,并相应地设置轮廓。
private RaycastHit lastHit;
void Update()
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(ray, out var hit);
//Physics.Raycast(cameraHolder.transform.position, cameraHolder.transform.forward, out var hit, Mathf.Infinity);
if (hit.transform != lastHit.transform)
{
if (hit.transform) // when raycast Begin
{
var outline = hit.transform.GetComponent<Outline>();
outline.OutlineWidth = 7;
}
else if (lastHit.transform) // when raycast out
{
var outline = lastHit.transform.GetComponent<Outline>();
outline.OutlineWidth = 0;
}
}
lastHit = hit;
}
Hint: I commented on your raycast code for testing. If you want to change the raycast code as before.