Unity学习日常问题记录九-关于Lookat与模型坐标系的相关的问题以及父子物体的刚体

从日常问题九与台球游戏有关的内容超出了1.0版本的内容,

为了让打完一个球之后不每次指向固定方向,比如我们希望指向自己要打的最小号球,如果不存在则指向台子中心Vector.zero的方向,成型后的代码如下
public class WhiteBallParticleSystemController : MonoBehaviour {

    public GameObject tableStick;
    public GameObject whiteBall;
    public GameObject SceneManager;
    private SceneManager sceneManager;
    Vector3 tempHitVector;

    GameObject[] numberBalls;
    // Use this for initialization
    void Start () {
        sceneManager = SceneManager.GetComponent<SceneManager> ();
        numberBalls = GameObject.FindGameObjectsWithTag("NumberBall");
        if (numberBalls.Length != 15)
            Debug.Log ("Less than 15 Balls?");
        for (int i = 0; i < numberBalls.Length; i++)
        {
            for (int j = i + 1; j < numberBalls.Length; j++) 
            {
                if(int.Parse(numberBalls[i].name) > int.Parse(numberBalls[j].name))
                {
                    GameObject temp = numberBalls[i];
                    numberBalls[i] = numberBalls[j];
                    numberBalls[j] = temp;
                }
            }
        }
    }
    
    void LateUpdate ()
    {
        tempHitVector = whiteBall.transform.position - tableStick.transform.position;
        tempHitVector = new Vector3 (tempHitVector.x, 0, tempHitVector.z);
        tempHitVector = tempHitVector + whiteBall.transform.position;
        gameObject.transform.LookAt (tempHitVector,Vector3.up);
    }

    //指向要打的号数最小的球,如果没有就指向台子的中心
    public void CurrentPlayerNextBallDirection(Vector3 oldWhiteBallAndStickOffset)
    {
        GameObject thePlayerMinimumNumberBall = null;
        Vector3 defaultHitPosition = Vector3.zero;
        if (sceneManager.nowPlayer == 1) 
        {
            if (sceneManager.player1.numberType == 1) 
            {
                for (int i = 0; i < 7; i++) 
                {
                    if (numberBalls [i].activeSelf == true) {
                        thePlayerMinimumNumberBall = numberBalls [i];
                        break;
                    }
                }
                if(thePlayerMinimumNumberBall== null) 
                    thePlayerMinimumNumberBall = numberBalls [7];//前面球都消失了,指向8号球
            } else if (sceneManager.player1.numberType == 2) 
            {
                for (int i = 8; i < 15; i++) 
                {
                    if (numberBalls [i].activeSelf == true) {
                        thePlayerMinimumNumberBall = numberBalls [i];
                        break;
                    }
                }
                if(thePlayerMinimumNumberBall== null) 
                    thePlayerMinimumNumberBall = numberBalls [7];//前面球都消失了,指向8号球
            }
        } else     if (sceneManager.nowPlayer == 2) 
        {
            if (sceneManager.player2.numberType == 1) 
            {
                for (int i = 0; i < 7; i++) 
                {
                    if (numberBalls [i].activeSelf == true) {
                        thePlayerMinimumNumberBall = numberBalls [i];
                        break;
                    }
                }
                if(thePlayerMinimumNumberBall== null) 
                    thePlayerMinimumNumberBall = numberBalls [7];//前面球都消失了,指向8号球
            } else if (sceneManager.player2.numberType == 2) 
            {
                for (int i = 8; i < 15; i++) 
                {
                    if (numberBalls [i].activeSelf == true) {
                        thePlayerMinimumNumberBall = numberBalls [i];
                        break;
                    }
                }
                if(thePlayerMinimumNumberBall== null) 
                    thePlayerMinimumNumberBall = numberBalls [7];//前面球都消失了,指向8号球
            }
        }
        if (thePlayerMinimumNumberBall != null)
            defaultHitPosition = thePlayerMinimumNumberBall.transform.position;

        Vector3 defualtHitVector = defaultHitPosition - whiteBall.transform.position;
        defualtHitVector = new Vector3 (defualtHitVector.x, 0, defualtHitVector.z);
        Vector3 oldWhiteBallAndStickOffsetWithoutY = new Vector3 (oldWhiteBallAndStickOffset.x, 0, oldWhiteBallAndStickOffset.z);
        Vector3 stickXZPosition = whiteBall.transform.position - defualtHitVector.normalized * oldWhiteBallAndStickOffsetWithoutY.magnitude;
        Vector3 stickPosition = new Vector3 (stickXZPosition.x, stickXZPosition.y + defualtHitVector.y, stickXZPosition.z);
        tableStick.transform.position = stickPosition;

        tableStick.transform.LookAt (whiteBall.transform.position);
//        tableStick.transform.tr
//        whiteBall.transform.loo

    }
}

这里需要球杆的位置和朝向指向白球和目标球的方向。开始本来想自己写个向量和本地坐标系旋转的相关内容,尝试了发现3位矢量的计算我没什么基础,硬推要太久,对下次做类似问题也没什么帮助,先放弃了。

然后决定用Unity提供的Transform.LookAt 本来开始想写类似LookAtwhiteBall.transform.position,tableStick.transform.InverseTransformPoint(oldWhiteBallAndStickOffset));

但发现Lookat只能使本地坐标系的z轴看向某个方向,然后就有点晕,尝试写自己的三维变换暂时未果后,查了一下有人说用父物体。

于是我建了一个Empty Object作为球杆的父物体,使此空物体的本地坐标系的z轴为球杆正向,原点也略微调整和白球中心点水平,然后调整子物体杆的位置。

最后让父物体Lookat白球。


根据这里的经验建议需要特定的指向最好都让物体本地坐标系的z轴正向指向,模型如果从3DMax中能将特定向设为正向最好直接做(比如枪口,喷射口),不行就在模型的父物体。遇到问题

1.父物体不推荐用空物体,我改了一次,把父物体改成一个透明的,刚体,碰撞体isTrigger勾中但相关函数不写,然后透明,后面会说为什么推荐如此。

2.在Scene的物体栏中TableStick下有模型,开始的时候父物体没有碰撞体和刚体,而在子物体TableStickEnds上写了碰撞体和刚体,力也作用在其上,这样就有个问题,每杆打问球杆和白球无限碰撞,我核对了每次TableStick到WhiteBall的距离是相等的,开始以为是杆变大了,可以拉远后第二次依然碰撞,杆也没明显变大,后来核对坐标和用个白色cube做父物体,如图

打击后

可看出cube位置对,而球杆动了,也就是说子物体的速度不会传给父物体,父物体没有动。


这里只能在cube上加碰撞体,刚体,不处理

3.在cube上加碰撞体,刚体,不处理而没删去子物体的刚体,白色cube会自己飞出去而球杆不动,这里如果子物体有刚体,不继承父物体速度,把子物体RigidBody删去就好了,子物体的碰撞体可以保留和进行相关编程。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值