unity 计时器_如何用unity 物理系统 实现Stickfight中火柴人的布娃娃效果(二)

c53f2d459a003001ffc9ec661388d227.png

上一期中,我们完成了角色在没有任何输入的情况下实现了站立平衡,这期,我们就来聊一下角色的运动吧。

玄夜smile:如何用unity 物理系统 实现Stickfight中火柴人的布娃娃效果(一) ,还没看过第一期的小伙伴们,可以先看下第一期的内容。

在做角色的运动之前,其实还存在一个细节需要处理

44cac2ae0c31426da039c1d827bb619f.png

大家请看第一期的最后一个演示视频,玩家在自由下落之后,如果没有任何外力的驱动,朝向会一直和初始方向一致(现在就是朝向屏幕),显然,我们是不希望出现这样的情况的,我们希望角色在接收到向左运动的指令之后,就会面朝左方,接收到向右运动的指令之后,就会面朝右方,并且,当角色从面朝左方更改为面朝右方的时候,是有转身过程的,而不是直接更新朝向,看到这里,大家可以先行思考一下这个问题,该怎么解决。

先分析一下,角色各个部件之间是用关节相连的,事实上,在运动过程中,各个刚体之间的相对位置和角度,时刻都处于不稳定的变化中,如果去对每个身体部位去做相关旋转的操作,显然是不合理的。所以,我们需要去操作一个部位,然后让它带动身体的其他部位一起转动,那选哪个部位合适呢,head?还是hip?古人有云,气运丹田,丹田,不就是我们hip的位置嘛,emm~就选hip了。

好了,言归正传,我们认真分析一下,对于head,我们在之前其实已经设计了一个上拉变力m_StandUpForce用于实时作用在上面了,若此时,再在head上添加旋转力,很容易就会让其陷入不稳定的状态,其次,head处于身体的最顶端,依靠head的转动,通过关节,去驱动全身组件转动,其实也不是一个合理的设计,恰恰相反,我们之前设计的hip,身上所有的关节连接,最终都是指向hip的,转动的时候也可以上下兼顾,正好完美的符合条件,所以综合这两点考虑,我选择了hip作为驱动点,来带动身体其他部位的转动。

接下来,就是如何让hip这个部位转动的问题了,我这里使用的是unity提供的物理接口Rigidbody.AddTorque(Vector3 torque,ForceMode mode)。

这个接口什么意思呢,也就是给刚体添加扭矩。学过物理的同学都知道右手定则,而这个接口是基于左手定则,在这个定则的手势下,将你的左手大拇指指向torque向量的方向,这样,刚体将会顺着你的其余手指旋向转动,ok,理解了这个接口的意义之后,我们就可以顺下去继续分析了

a43b8c53546b7532900bd70096a354df.png

如上图,hip.forword代表的是hip刚体的前方,也就是角色的朝向,此时当输入向左指令后,我们希望hip.forword->left,结合刚刚对扭矩接口的分析,我们很容易得到,torque=a*vector3.up,torque就代表长度为a,方向为vector3.up(在这里,是垂直于屏幕向外)的向量,torque作用于刚体时,hip就会顺着torque扭矩向left转动,但是,我们并不希望hip绕着这个方向一直转动,而是到了left,停下来,所以,我们需要实时获取left和hip.forword的角度angle,令a=angle,这样,当角色朝向和left相同时,torque就会被置0,角色的转动就停止啦。

到这里,这个问题也就解决了,为此,我在character父节点下,建立了一个TargetRotation空节点作为辅助节点,如下图

99bfbdc048559ea5509384f5907af9d4.png

TargetRotation的朝向始终指向input的朝向,这样,就能在update中实时获取angle,在刚体上施加正确的扭矩了。下面就直接上代码,创建BalanceRotation脚本,并挂在character父节点下

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

//控制人物  左右 旋转
public class BalanceRotation : MonoBehaviour {
    

    player mplayer;
    private Transform mtarget;                           //世界中作为角色转向的标杆
     public Transform mTarget
    {
    
        get
        {
    
            if(!mtarget)
            {
    
                mtarget = transform.Find("TargetRotation");
            }
            return mtarget;
        }
    }

    private Rigidbody mhip;
    private Vector3 mAngle_direction;                //叉乘向量
    private float mAngle;                            //夹角
    public int TorqueForce = 30;

    JointAnimationMgr _jointAnimationMgr;

    void Start()
    {
    
        mplayer = GetComponent<player>();
        _jointAnimationMgr = mplayer.m_JointAnimationMgr;
        mhip = _jointAnimationMgr.m_hip;
    }

    private void Update()
    {
    
        if (Input.GetKey(KeyCode.A))
        {
    
            mtarget.rotation = Quaternion.Euler(0, -90, 0);
        }
        else if (Input.GetKey(KeyCode.D))
        {
    
            mtarget.rotation = Quaternion.Euler(0, 90, 0);
        }
    }

    void FixedUpdate()
    {
    
        mAngle = Vector3.Angle(mhip.transform.forward, mTarget.forward);                //实时获取TargetRotation与hip的角度差
        mAngle_direction = Vector3.Cross(mhip.transform.forward, mtarget.forward);
        AddTorqueWithHip();
    }

    /// <summary>
    /// 根据target点和角色旋转的角度差给对应方向,对应大小力的扭矩
    /// </summary>
    void AddTorqueWithHip()
    {
    
        if (mAngle_direction.y>0)
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值