繁体   English   中英

transform.position 的问题

[英]Issue with transform.position

我正在尝试制作一个简单的乒乓球游戏,一旦玩家或敌人得分,他们就会在球场上重新定位。

我在敌人身上有这个脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyBehavior : MonoBehaviour
{
    Vector3 ballPosition;
    Vector3 paddlePosition;
    float movementSpeed = 0.1f;

    public Transform target;
    public float maxAngle = 35.0f;
    private Quaternion baseRotation;
    private Quaternion targetRotation;




    // Start is called before the first frame update
    void Start()
    {
        baseRotation = transform.rotation;
    }

    // Update is called once per frame
    void Update()
    {

        ballPosition = GameObject.Find("Ball").transform.position;
            paddlePosition = this.transform.position;


            if (paddlePosition.z < ballPosition.z)
            {
                paddlePosition.z += movementSpeed;
            }
            else if (paddlePosition.z > ballPosition.z)
            {
                paddlePosition.z -= movementSpeed;
            }
            transform.position = paddlePosition;

            Vector3 look = target.transform.position - transform.position;
            look.z = 0;

            Quaternion q = Quaternion.LookRotation(look);

            if (Quaternion.Angle(q, baseRotation) <= maxAngle)
            {
                targetRotation = q;
            }


            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2.0f);
        }
}

然后附加到目标的目标脚本如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Goal : MonoBehaviour
{
    public GameObject Ball;
    public GameObject Player;
    public GameObject Enemy;
    public Text Player2Score;
    public Text Player1Score;
    int Player2ScoreText = 0;
    int Player1ScoreText = 0;
    Rigidbody ballrig;
    Rigidbody playerrig;
    Rigidbody enemyrig;
    public ParticleSystem Particles;
    float timeLeft = 1.0f;
    public bool slowMo = false;
    // Start is called before the first frame update
    void Start()
    {
        ballrig = Ball.GetComponent<Rigidbody>();
        playerrig = Player.GetComponent<Rigidbody>();
        enemyrig = Enemy.GetComponent<Rigidbody>();

    }

    // Update is called once per frame
    void Update()
    {
        if (slowMo == true)
        {
            timeLeft -= Time.deltaTime;
            if (timeLeft < 0)
            {
                slowMo = false;
                timeLeft = 1.0f;
                Time.timeScale = 1f;
            }

        }
    }
    private void OnTriggerEnter(Collider other)
    {

        if (other.name == "Ball" && name == "Player_Goal")
        {
            slowMo = true;
            Time.timeScale = 0.5f;
            Explode();
            Player2ScoreText += 1;
            Player2Score.text = ("" + Player2ScoreText);
            Ball.transform.position = new Vector3(0f, 4f, 0f);
            Player.transform.position = new Vector3(-20f, 2f, 0f);
            Enemy.transform.position = new Vector3(20f, 2f, 0f);
            ballrig.velocity = Vector3.zero;
            ballrig.angularVelocity = Vector3.zero;
            playerrig.velocity = Vector3.zero;
            playerrig.angularVelocity = Vector3.zero;
            enemyrig.velocity = Vector3.zero;
            enemyrig.angularVelocity = Vector3.zero;
            int whoGetsIt = Random.Range(0, 2);
            if (whoGetsIt >= 1)
            {
                Vector3 Impulse = new Vector3(-10f, 5f, Random.Range(-10f, 10f));
                Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
            }
            else
            {
                Vector3 Impulse = new Vector3(10f, 0f, Random.Range(-10f, 10f));
                Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
            }

        }
        else if (other.name == "Ball" && name == "Enemy_Goal")
        {
            slowMo = true;
            Time.timeScale = 0.5f;
            Explode();
            Player1ScoreText += 1;
            Player1Score.text = ("" + Player1ScoreText);
            Ball.transform.position = new Vector3(0f, 4f, 0f);
            Player.transform.position = new Vector3(-20f, 2f, 0f);
            Enemy.transform.position = new Vector3(20f, 2f, 0f);
            ballrig.velocity = Vector3.zero;
            ballrig.angularVelocity = Vector3.zero;
            playerrig.velocity = Vector3.zero;
            playerrig.angularVelocity = Vector3.zero;
            enemyrig.velocity = Vector3.zero;
            enemyrig.angularVelocity = Vector3.zero;
            int whoGetsIt = Random.Range(0, 2);
            if (whoGetsIt >= 1)
            {
                Vector3 Impulse = new Vector3(-10f, 5f, Random.Range(-10f, 10f));
                Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
            }
            else
            {
                Vector3 Impulse = new Vector3(10f, 0f, Random.Range(-10f, 10f));
                Ball.GetComponent<Rigidbody>().AddForce(Impulse, ForceMode.Impulse);
            }
        }
    }
    void Explode()
    {
        Particles.Play();
    }
}

现在,在有人得分后,球会正确重新定位,但由于某种原因,玩家和敌人没有。 是因为他们在更新 function 中都有代码,因此代码“覆盖”了重新定位的命令? 如果是这样,我该如何解决?

我可以看到您的玩家正在使用RigidbodyRigidbody2D

每当涉及刚体时,您不应通过transform设置任何 position,而应使用相应的刚体方法,例如MovePositionMoveRotation或通过Rigibody.position直接设置它们Rigidbody.rotation

....
    slowMo = true;
    Time.timeScale = 0.5f;
    Explode();
    Player2ScoreText += 1;
    Player2Score.text = ("" + Player2ScoreText);
    Ball.GetComponent<Rigidbody>().position = new Vector3(0f, 4f, 0f);
    Player.GetComponent<Rigidbody>().position = new Vector3(-20f, 2f, 0f);
    Enemy.GetComponent<Rigidbody>().position = new Vector3(20f, 2f, 0f);
    ballrig.velocity = Vector3.zero;
    ballrig.angularVelocity = Vector3.zero;
    playerrig.velocity = Vector3.zero;
    playerrig.angularVelocity = Vector3.zero;
    enemyrig.velocity = Vector3.zero;
    enemyrig.angularVelocity = Vector3.zero;
    int whoGetsIt = Random.Range(0, 2);
....

然后也在EnemyBehaviour -> 它应该是FixedUpdate并且看起来像

public Rigidbody target;

Rigidbody ball;
Rigidbody ownRigidbody;

void Start()
{
    baseRotation = transform.rotation;

    // Get reference only ONCE and store them1
    ball = GameObject.Find("Ball").GetComponent<Rigidbody>();
    ownRigidbody = GetComponent<Rigidbody>();
}

// Update is called once per frame
void FixedUpdate()
{
    ballPosition = ball.position;
    paddlePosition = ownRigidbody.position;

    if (paddlePosition.z < ballPosition.z)
    {
        paddlePosition.z += movementSpeed;
    }
    else if (paddlePosition.z > ballPosition.z)
    {
        paddlePosition.z -= movementSpeed;
    }
    ownRigidbody.MovePosition(paddlePosition;)

    Vector3 look = target.position - ownRigidbody.position;
    look.z = 0;

    Quaternion q = Quaternion.LookRotation(look);

    if (Quaternion.Angle(q, baseRotation) <= maxAngle)
    {
        targetRotation = q;
    }


    ownRigidbody.MoveRotation(Quaternion.Slerp(ownRigidbody.rotation, targetRotation, Time.deltaTime * 2.0f));
}

因为在这里你想要平滑插值 position

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM