Unity3D 里IK手柄的用运

本文介绍了一个Unity射击游戏中如何通过动画控制器实现武器的显示与隐藏,并利用IK(Inverse Kinematics)来完成角色左右手握持武器的效果。此外,还详细讲解了如何使用射线投射来确定武器的目标位置。
实现功能:1.当点击鼠标右键,左右手扶住武器, 进入射击状态
                   

                 2.再次点击鼠标右键,武器消失,取消射击状态                                            
                                                                                                                                                           
                                                


解决方法:                         ①将武器放置为头部的子物体
                                          ②在武器体下面设置3个子空物体,分别作为子弹出射点,左手放置位置,右手放置位置。
                                          

            void  OnAnimatorIK(int  layerIndex)
           {
                 float  aim =  animator.GetFloat("Aim");
                 if(layerIndex == 0) {
                             if(target!=null)
                             {
                                 //设置武器瞄准目标的位置
                                Vector3  tPosition  =  target.transform.position;
                                tPosition.y =  tPosition.y + 0.2f*(tPosition- animator.rootPosition).magnitude;
                                animator.SetLookAtPosition(tPosition);
                                animator.SetLookAtWeight(aim,0.5f,.5f,0.0f,0.5f);
                              //设置武器消失与出现
                               if (bazoo != null)
                                     {
                                      float fire = animator.GetFloat("Fire");
                                      Vector3 pos = new Vector3(-0.148f, -0.2518f, -0.1828f);
                                      Vector3 scale = new Vector3(0.2f, 0.68f, 0.2f);
                                      pos.x -= fire * 0.2f;
                                      scale = scale * aim;
                                      bazoo.transform.localScale = scale;            当aim值为0时,大小变成了0,武器就消失了
                                  // bazoo.transform.localPosition = pos;
                                     }        
                        }
                }
                if (layerIndex == 1 )
                {      

                         //设置左手IK权重
                       if(leftHand!=null)
                       {
                         animator.SetIKPosition(AvatarIKGoal.LeftHand,leftHand.transform.position);
                         animator.SetIKPositionWeight(AvatarIKGoal.LeftHand,aim);
                       }
                      if(rightHand!=null)
                      {
                       //设置右手IK权重
                       animator.SetIKPosition(AvatarIKGoal.RightHand,rightHand.transform.position);
                       animator.SetIKPositionWeight(AvatarIKGoal.RightHand,aim);
                       }
                 }
    }

              //发射子弹
             //射击逻辑
                      if(Input.GetButton("Fire1")&&fire<0.01f&&aim>0.99f)
                      {
                               animator.SetFloat("Fire",1);
                                if(bullet!=null&&FirePosition!=null)
                       {
                               GameObject  newBullet = Instantiate(bullet,FirePosition.transform.position,Quaternion.Euler(0,0,0)) as  GameObject; 
                               Rigidbody  rb = newBullet.GetComponent<Rigidbody>();
                               if(rb!=null)
                      {
                               rb.velocity  =   FirePosition.transform.TransformDirection(Vector3.forward*20);
                      }
          }
   }

            源代码:using UnityEngine; 
            using System.Collections;

public class fireAndAnimation : MonoBehaviour {
protected Animator  animator;
public GameObject target = null;
    public GameObject leftHand = null;
    public GameObject rightHand = null;
    public GameObject bazoo = null;
    public GameObject bullet = null;
    public GameObject FirePosition = null;
private  bool  load  =  false;
// Use this for initialization
void Start () {
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
if (animator)
{
float  aim =  animator.GetFloat("Aim");
float  fire  =  animator.GetFloat("Fire");
//  瞄准逻辑
 if (Input.GetButton("Fire2"))
{
if(!load  && ( aim<0.01))
{
load = true;
}  else  if (load && aim >0.99   )
{
load = false;
}
}
  animator.SetFloat("Aim",load?1:0,0.1f,Time.deltaTime);
//射击逻辑
if(Input.GetButton("Fire1")&&fire<0.01f&&aim>0.99f)
{
animator.SetFloat("Fire",1);
if(bullet!=null&&FirePosition!=null)
{
GameObject  newBullet = Instantiate(bullet,FirePosition.transform.position,Quaternion.Euler(0,0,0)) as  GameObject; 
Rigidbody  rb = newBullet.GetComponent<Rigidbody>();
if(rb!=null)
{
  rb.velocity  =   FirePosition.transform.TransformDirection(Vector3.forward*20);
}
}
   }
else
{
animator.SetFloat("Fire",0,0.1f,Time.deltaTime);
}
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
animator.SetFloat("Speed", h*h+v*v);
            animator.SetFloat("Direction", h, 0.25f, Time.deltaTime);
}
}
     void  OnAnimatorIK(int  layerIndex)
{
float  aim =  animator.GetFloat("Aim");
if(layerIndex == 0)
{
if(target!=null)
{
Vector3  tPosition  =  target.transform.position;
tPosition.y =  tPosition.y + 0.2f*(tPosition- animator.rootPosition).magnitude;
animator.SetLookAtPosition(tPosition);
animator.SetLookAtWeight(aim,0.5f,.5f,0.0f,0.5f);
if (bazoo != null)
                {
                    float fire = animator.GetFloat("Fire");
                    Vector3 pos = new Vector3(-0.148f, -0.2518f, -0.1828f);
                    Vector3 scale = new Vector3(0.2f, 0.68f, 0.2f);
                    pos.x -= fire * 0.2f;
                    scale = scale * aim;
                    bazoo.transform.localScale = scale;
                    bazoo.transform.localPosition = pos;
                }        
}
}
if (layerIndex == 1 )
{
if(leftHand!=null)
{
animator.SetIKPosition(AvatarIKGoal.LeftHand,leftHand.transform.position);
animator.SetIKPositionWeight(AvatarIKGoal.LeftHand,aim);

}
if(rightHand!=null)
{
animator.SetIKPosition(AvatarIKGoal.RightHand,rightHand.transform.position);
animator.SetIKPositionWeight(AvatarIKGoal.RightHand,aim);

}
}
 
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值