簡體   English   中英

沿它在 Unity 中移動的方向旋轉 object

[英]Rotate object in the direction it's moving in Unity

我有一個 2D object,它簡單地向前移動,直到它撞到另一個 object,其中物理材料導致 object 從另一個 object 反彈。

我不是最擅長繪圖的,但這是我想要它做的事情的說明:(球體中的箭頭表示球體當前面向的方向)

在此處輸入圖像描述

在此處輸入圖像描述

我把它的物理部分寫得很好,但是物理材質不會旋轉游戲對象,所以實際結果看起來更像這樣:

在此處輸入圖像描述

我知道你可以很容易地通過變換設置 object 的旋轉,但是你如何獲得游戲對象的移動方向,然后將旋轉設置為該方向?

首先,你需要知道圖像的局部方向應該指向運動的方向。 這取決於您的設置,並且問題不包含足夠的信息來准確了解。 它可能是Vector3.upVector3.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM