[英]Rotate object in the direction it's moving in Unity
首先,你需要知道圖像的局部方向應該指向運動的方向。 這取決於您的設置,並且問題不包含足夠的信息來准確了解。 它可能是Vector3.up
或Vector3.right
。 當然,世界方向是從速度得知的。
Vector3 worldDirectionToPointForward = rb2d.velocity.normalized;
Vector3 localDirectionToPointForward = Vector3.right;
然后,您想要圍繞 z 軸旋轉精靈,使局部方向指向該方向。 您可以使用transform.TransformDirection
找到球“指向”的當前方向,然后使用Vector3.SignedAngle
計算角度:
Vector3 currentWorldForwardDirection = transform.TransformDirection(
localDirectionToPointForward);
float angleDiff = Vector3.SignedAngle(currentWorldForwardDirection,
worldDirectionToPointForward, Vector3.forward);
然后,使用transform.Rotate
將其圍繞 z 軸旋轉該量。
transform.Rotate(Vector3.forward, angleDiff);
我會在與牆壁發生碰撞后這樣做。 另一種方法是將它放在LateUpdate
中,盡管這可能會干擾其他單一行為中LateUpdate
中發生的其他事情。 但是, LateUpdate
方法最容易演示,因此我將在此處進行演示:
void LateUpdate()
{
Vector3 worldDirectionToPointForward = rb2d.velocity.normalized;
Vector3 localDirectionToPointForward = Vector3.right;
Vector3 currentWorldForwardDirection = transform.TransformDirection(
localDirectionToPointForward);
float angleDiff = Vector3.SignedAngle(currentWorldForwardDirection,
worldDirectionToPointForward, Vector3.forward);
transform.Rotate(Vector3.forward, angleDiff, Space.World);
}
我目前無法對此進行測試,但以下應該有效。
Vector3 prevPosition = Vector3.zero;
void Update()
{
if(prevPosition != Vector3.zero)
{
Vector3 movementDir = transform.position - prevPosition;
transform.rotation = Quaternion.LookRotation(movementDir, Vector3.Up);
}
prevPosition = transform.position;
}
我們所做的就是比較最后一幀的對象 position 和這一幀的對象 position,減去這些位置得到一個向量,然后旋轉以沿着該向量面對。
在更新方法中,每一幀都會調用它,如果你只有一個球也沒問題,但如果你有幾千個,你可能想進入一個只在碰撞后調用的方法。
在物理處於活動狀態時手動旋轉可能會給您帶來一些古怪的結果,但是這里有
public class FaceVelocity : MonoBehaviour
{
private Rigidbody rigidBody;
void Awake()
{
rigidBody = getComponent<RigidBody2D>();
}
//Apply rotation in late update to make sure it's not undone by physics
void LateUpdate()
{
transform.right = rigidBody.velocity.normalized
}
}
如果你的物體在與某物接觸時旋轉(也就是它最有可能接觸的地方),它可能會擾亂物理學。 最好使用父 object 來學習物理,使用子 object 來學習視覺效果。
public class FaceVelocity : MonoBehaviour
{
private Rigidbody rigidBody;
void Awake()
{
rigidBody = transform.parent.getComponent<RigidBody2D>();
}
//Apply rotation in late update to make sure it's not undone
void LateUpdate()
{
transform.right = rigidBody.velocity.normalized
}
}
雖然對我來說,聽起來你甚至不需要剛體,粒子物理學就足夠了。 如果不使用剛體,請自行計算速度方向:
public class FaceVelocity : MonoBehaviour
{
private Vector3 prevPos;
void Awake()
{
prevPos = transform.position;
}
//Apply rotation in late update to make sure it's not undone
void LateUpdate()
{
transform.right = (transform.position - prevpos).normalized
}
}
我希望這個腳本能幫助你
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Reflect : MonoBehaviour
{
//3d Project
public int reflections;
public float maxLenght;
private Ray ray;
private RaycastHit hit;
private Vector3 direction;
Vector3 pos;
private void Awake()
{
reflections = 5;
maxLenght = 200;
pos = gameObject.transform.position;
GetNextPoint(1);
}
private void Update()
{
if (Vector3.Distance(gameObject.transform.position, pos) >0.7f)
{
//move
transform.position += transform.forward/10;
}
else
{
GetNextPoint(2);
}
}
void GetNextPoint(int num)
{
ray = new Ray(transform.position, transform.forward);
float remaningLength = maxLenght;
int t = 0;
for (int i = 0; i < reflections; i++)
{
if (Physics.Raycast(ray.origin, ray.direction, out hit, remaningLength))
{
ray = new Ray(hit.point, Vector3.Reflect(ray.direction, hit.normal));
t++;
if (t == num)
{
gameObject.transform.LookAt(hit.point);
pos = hit.point;
break;
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.