使用对象来回旋转 raycast2D
Posted
技术标签:
【中文标题】使用对象来回旋转 raycast2D【英文标题】:Rotating raycast2D back and forth with object 【发布时间】:2022-01-09 20:54:53 【问题描述】:我做了一个圆圈,并在上面附加了一个激光盒。
激光将向其上 y 轴(垂直向上)发射光线投射。我还添加了一个线渲染器来查看它。
我希望光线投射来回旋转 90 度。有点像它扫描顶部的所有内容。我的问题是它不能正常工作。它确实来回旋转,但如果我移动激光物体的 x 位置,光线投射将以一个奇怪的角度旋转。
激光物体的脚本
public LineRenderer lineRenderer;
public LayerMask layerMask;
public float laserSpeed;
Vector3 pointA;
Vector3 pointB;
Vector3 castPosition;
RaycastHit2D rayCast;
float time;
void Start()
pointA = transform.eulerAngles + new Vector3(0f, 0f, 90f);
pointB = transform.eulerAngles + new Vector3(0f, 0f, -90f);
void Update()
time = Mathf.PingPong(Time.time * laserSpeed, 1);
transform.eulerAngles = Vector3.Lerp(pointA, pointB, time);
castPosition = new Vector3(transform.position.x, transform.position.y, transform.position.z);
rayCast = Physics2D.Raycast(castPosition, transform.TransformDirection(Vector2.up), 10f, layerMask);
lineRenderer.SetPosition(0, castPosition);
lineRenderer.SetPosition(1, transform.TransformDirection(Vector2.up) * 10f);
【问题讨论】:
@derHugo 好吧,我刚开始统一,所以我把一小段代码混合在一起。你能展示一下正确的做法吗? 【参考方案1】:将eulerAngles
用于连续动画非常“危险”。 Unity 将旋转存储为Quaternion
,并且有多种方法可以在欧拉空间中表示它们!
当您阅读
.eulerAngles
属性时,Unity 会将Quaternion
的内部旋转表示转换为欧拉角。因为,使用欧拉角表示任何给定旋转的方法不止一种,因此您读出的值可能与您分配的值完全不同。如果您尝试逐渐增加值以生成动画,这可能会导致混淆。为避免此类问题,推荐使用旋转的方法是在阅读
.eulerAngles
时避免依赖一致的结果,尤其是在尝试逐渐增加旋转以产生动画时。有关实现此目的的更好方法,请参阅Quaternion * operator
。
所以你应该去Quaternion
并做例如
然后您使用transform.TransformDirection(Vector2.up)
,这是一个方向,并将其作为位置传递给您的线渲染器。
你想要的,其实是组合的位置
transform.position + transform.up
所以应该是在一起吧
public LineRenderer lineRenderer;
public LayerMask layerMask;
public float laserSpeed;
private Quaternion originalRotation;
private Quaternion minRotation;
private Quaternion maxRotation;
void Start()
originalRotation = transform.rotation;
minRotation = originalRotation * Quaternion.Euler(0, 0, -90);
maxRotation = originalRotation * Quaternion.Euler(0, 0, 90);
void Update()
// Note that Vector3 is a "struct" -> there is no need to manually use "new Vector3(transform.position.x, ...)"
var startPosition = transform.position;
lineRenderer.SetPosition(0, startPosition);
var factor = Mathf.PingPong(Time.time * laserSpeed, 1);
// instead of the eulers rather use Quaternion
transform.rotation = Quaternion.Lerp(minRotation, maxRotation, factor);
// "transform.up" basically equals using "transform.TransformDirection(Vector3.up)"
var rayCast = Physics2D.Raycast(startPosition, transform.up, 10f, layerMask);
if(rayCast.collider)
// when you hit something actually use this hit position as the end point for the line
lineRenderer.SetPosition(1, rayCast.point);
else
// otherwise from the start position go 10 units in the up direction of your rotated object
lineRenderer.SetPosition(1, startPosition + transform.up * 10f);
【讨论】:
感谢您的详尽解释。效果很好! @stalwart1014 如果有帮助,别忘了accept这个答案!以上是关于使用对象来回旋转 raycast2D的主要内容,如果未能解决你的问题,请参考以下文章