暴灵珊 发表于 2025-8-2 00:09:55

第三人称——骑马系统以及交互动画

骑马系统

人物在马上的脚本

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

public class ThirdPersonRidingHorse : MonoBehaviour
{
   
    public GameObject horse;
    public bool isOnHorse;

    //void OnInteract()
    //{
    //    var thirdPersonMove = GetComponent<ThirdPersonMove>();
    //    thirdPersonMove.enabled = false;
    //    var pos = horse.transform.Find("Pos_UpToHorse");

    //}

    CharacterController characterController;
    Animator animator;
    ThirdPersonMove thirdPersonMove;

    private void Awake()
    {
      characterController = GetComponent<CharacterController>();
      animator = GetComponent();
      thirdPersonMove = GetComponent<ThirdPersonMove>();
    }

    private void Update()
    {
      if (isOnHorse)
      {
            var axisX = Input.GetAxis("Horizontal");
            var axisY = Input.GetAxis("Vertical");
            animator.SetFloat("AxisX", axisX);
            animator.SetFloat("AxisY", axisY);
      }
      Ride();
    }

    void Ride()
    {
      //上马
      if (!isOnHorse)
      {
            if (Input.GetKeyDown(KeyCode.F))
            {
                isOnHorse = true;
                transform.rotation = horse.transform.rotation;
                transform.position = horse.transform.position;
                //将角色放到马上
                var playerPoint = horse.transform.Find("PlayerPoint");
                transform.SetParent(playerPoint);
                transform.localPosition = Vector3.zero;
                //在马上禁用角色的characterController和move
                characterController.enabled = false;
                thirdPersonMove.enabled = false;
                //开启马的输入控制脚本
                horse.GetComponent<MalbersInput>().enabled = true;

                //切换马上动作状态,即权重从0到1
                animator.SetLayerWeight(2, 1f);
            }
      }
      //下马
      else
      {
            if (Input.GetKeyDown(KeyCode.F))
            {
                isOnHorse = false;
                if (horse != null)
                {
                  //删除马之前设置角色位置
                  transform.SetParent(null);
                  transform.position = horse.transform.position;
                  transform.rotation = horse.transform.rotation;
                  //下马后恢复角色的characterController和move
                  characterController.enabled = true;
                  thirdPersonMove.enabled = true;
                  //关闭马的输入控制脚本
                  horse.GetComponent<MalbersInput>().enabled = false;
                  //关闭马上动作层
                  animator.SetLayerWeight(2, 0f);

                }
            }
      }

    }
}马的部分——插件:Horse Animset Pro Riding System 4.0.1.unitypackage


状态机设置

先学习怎么做场景交互

以常见的开宝箱交互为例:
1)先建一个可开盖宝箱的模型


2)在Box的子级中建立一个空的GameObject,当作角色开始播放交互动画的位置

3)在Box的animation窗口中建立动画——Box的开盖动画


4)这里需要把开盖动画的Loop Time给取消勾选

5)来到Timeline窗口,新建一个Box的Timeline,把Box的开盖动画和角色交互的动画拖进去

注:角色动画是mixamo里找的

角色的Track在k帧的时候选上 角色的animator,在k完之后就记得要取消勾选animator

也要记得修改该动画的名字,后面脚本会用到

为了保证开盖动画在人物动画播完后仍然还在播,点开开盖动画的Animation Track,设置为continue

6)把人物移到和PlayerStandPosition同一个位置,追求完美可以k一下开盖动画和角色动画的匹配度,并加上过渡动画(这里我就懒得弄了,因为只是学习怎么做动画交互系统)
7)为Box加上Tag-Box

8)为Box加上Trigger碰撞体

9)取消勾选Play On Awake,不然还没触发就开始播动画了


OK,交互动画匹配好了,下面写脚本控制角色到达一个Box周围的Trigger碰撞体区域,按下交互的Input按键才触发动画
脚本逻辑:
在碰撞体区域按下按键->开始找tag为Box的GameObject,找到的对象就是Box->在Box的子级中找名为PlayerStandPosition的对象->更新角色位置、朝向->在Box的playerableAsset中找到PlayerTrack,播放相应的BoxTimeline
脚本如下:
PlayerOpenBox.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.InputSystem;

public class PlayerOpenBox : MonoBehaviour
{
    bool isPlaying = false;

    IEnumerator OnInteract()
    {
      if (list.Count > 0 && isPlaying == false)
      {
            isPlaying = true;

            var thirdPersonMove = GetComponent<ThirdPersonMove>();
            thirdPersonMove.enabled = false;
            var thirdPersonJump = GetComponent<ThirdPersonJump>();
            thirdPersonJump.enabled = false;
            var thirdPersonRoll = GetComponent<ThirdPersonRoll>();
            thirdPersonRoll.enabled = false;

            var director = list;
            list.RemoveAt(0);
            var pos = director.transform.Find("PlayerStandPosition");
            transform.position = pos.position;
            //Debug.Log(pos.position);
            transform.rotation = pos.rotation;
            var animator = GetComponent();
            foreach (var output in director.playableAsset.outputs)
            {
                if (output.streamName == "PlayerTrack")
                {
                  director.SetGenericBinding(output.sourceObject, animator);
                  break;
                }
            }
            director.Play();
            while(director.state == PlayState.Playing)
            {
                yield return null;
            }
            thirdPersonMove.enabled = true;
            thirdPersonJump.enabled = true;
            thirdPersonRoll.enabled = true;
            isPlaying = false;
      }
    }

    List<PlayableDirector> list = new List<PlayableDirector>();
    private void OnTriggerEnter(Collider other)
    {
      if (other.gameObject.tag == "Box")
      {
            var director = other.gameObject.GetComponent<PlayableDirector>();
            if (director != null && !list.Contains(director))
            {
                list.Add(director);
            }
            //Debug.Log(transform.position);
      }
    }

    private void OnTriggerExit(Collider other)
    {
      if (other.gameObject.tag == "Box")
      {
            var director = other.gameObject.GetComponent<PlayableDirector>();
            if (director != null && list.Contains(director))
            {
                list.Remove(director);
            }
      }
    }

}脚本挂在角色身上
效果如下:

上下马交互系统


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 第三人称——骑马系统以及交互动画