Unity3D仿星露谷物语开发23之拿起道具的动画

1、目标

当点击库存栏上可以carry的道具时,首先arms替换为carry状态,同时手上拿着被点击的道具。当再次点击同一个道具时,ams替换为idle状态,手上放下之前的道具。

这个最主要的是要学会使用AnimatorOverrideController类。

2、概念

AnimatorOverrideController类:用于控制动画其重写控制器的接口。

动画器重写控制器的用途是重写某个控制器的动画剪辑,从而为给定化身定制动画。在运行时基于相同的AnimatorController交换Animator.runtimeAnimatorController和AnimatorOverrideController不会重置状态机的当前状态。

(1)一般使用方法

定义变量:AnimatorOverrideController animatorOverrideController;

初始化变量:animatorOverrideController = new AnimatorOverrideController(animator.runtimeAnimatorController);

animator.runtimeAnimatorController = animatorOverrideController;

通过上面的赋值,后续对animatorOverrideController的修改将直接作用于animator.runtimeAnimatorController(运行态的动画控制器)。

运行中更新动画:animatorOverrideController["shot"] = weaponAnimationClip[weaponIndex];

(2)每帧更新多个动画剪辑

使用AnimatorOverrideController.ApplyOverrides方法,它能够将动画器剪辑绑定重新分配的数量减少到每次调用只有一个。

定义新老动画的映射:List<KeyValuePair<AnimationClip, AnimationClip>> clipOverrides;

初始化:animatorOverrideController.GetOverrides(clipOverrides);

运行中更新动画:animatorOverrideController.ApplyOverrides(clipOverrides);

其中ApplyOverrides函数:对该动画器重写控制器应用写列表

GetOverrides函数:获取该动画器重写控制器中当前定义的动画剪辑重写的列表。

3、思路

首先,创建SO_AnimationType类描述所有的动画剪辑。

其次,创建CharacterAttribute类定义想要替换的动画信息。

然后,基于AnimatorOverrideController类,根据CharacterAttribute类定义的动画信息,将Player下所有当前状态的动画替换为CharacterAttribute类定义的动画。

最后,如果是carry状态,给Player下的equippedItem对象赋以点击道具的图像。

4、创建可交互的动画的描述类

在Assets -> Scripts -> Animation下创建SO_AnimationType.cs脚本。

[CreateAssetMenu(fileName = "so_AnimationType", menuName = "Scriptable Objects/Animation/Animation Type")]
public class SO_AnimationType : ScriptableObject
{
    public AnimationClip animationClip;  // a reference to the actual animation clip  动画剪辑
    public AnimationName animationName;  // an enum of the animation name like "AnimationName.IdleUp"  动画名称
    public CharacterPartAnimator characterPart; // the gameobject name the Animator is on that controls these animation clips e.g. "arms" 动画位置对象
    public PartVariantColour partVariantColour; // to enable colour variations on a animation type to be specified e.g. "none", "bronze", "silver", "gold" 动画颜色变化
    public PartVariantType partVariantType; // the variant type to specify what variant this animation type refers to e.g. "none", "carry", "hoe", "pickaxe", "axe"..etc 动画类型
}

5、创建一个角色属性结构描述想要交换的动画

在Assets -> Scripts -> Animation 下创建CharacterAttribute.cs脚本,目标动画剪辑的属性结构。

[System.Serializable]
public struct CharacterAttribute
{
    public CharacterPartAnimator characterPart;   // 示例: CharacterPartAnimator.arms 动画位置对象
    public PartVariantColour partVariantColour;  // 示例: ParVariantColour.none 动画颜色变化
    public PartVariantType partVariantType;  // 示例: PartVariantType.carry 动画类型

    public CharacterAttribute(CharacterPartAnimator characterPart, PartVariantColour partVariantColour, PartVariantType partVariantType) 
    {
        this.characterPart = characterPart;
        this.partVariantColour = partVariantColour;
        this.partVariantType = partVariantType;
    }
}

6、创建Enum对象

在Assets -> Scripts -> Enums -> Enums.cs 中增加如下信息:

public enum AnimationName
{
    idleDown,
    idleUp,
    idleLeft,
    idleRight,
    walkUp,
    walkDown,
    walkLeft,
    walkRight,
    runUp,
    runDown,
    runLeft,
    runRight,
    useToolUp,
    useToolDown,
    useToolLeft,
    useToolRight,
    swingToolUp,
    swingToolDown,
    swingToolLeft,
    swingToolRight,
    liftToolUp,
    liftToolDown,
    liftToolLeft,
    liftToolRight,
    holdToolUp,
    holdToolDown,
    holdToolLeft,
    holdToolRight,
    pickUp,
    pickDown,
    pickLeft,
    pickRight,
    count
}


public enum CharacterPartAnimator
{
    body,
    arms,
    hair,
    tool,
    hat,
    count
}

public enum PartVariantColour
{
    none,
    count
}

public enum PartVariantType
{
    none,
    carry,
    hoe,
    pickaxe,
    axe,
    scythe,
    wateringCan,
    count
}

7、创建动画重写控制器AnimationOverrides

流程:

1)创建2个动画剪辑的映射,第1个是 动画剪辑 到 动画描述类的映射,第2个是 动画表示名 到 动画描述类的映射。

2)通过配置的动画描述信息,分别填充上一步的两个映射表。

3)输入characterAttributesList,需要的动作的动画描述信息,比如partVariantType为carry的动画描述。

4)根据characterPart(比如arm)扫描当前角色下已有的动画剪辑,找到characterPart这个名称的动画剪辑为currentAnimator

5)找到characterPart对应controller下所有的动画剪辑,得到animationsList列表

我们找到了arms的animatorController,

再点击进入控制器的Run分类,

点击RunRight,其对应的动画剪辑为ArmsNoneNoneRunRight = characterPart + partVariantColour + partVariantType + animationName

6)在animationsList列表中,依次遍历得到动画剪辑animationClip对应的动画描述类so_AnimationType(已有的动画)

7)然后根据characterAttribute(目标动画属性结构)中的信息+ 动画名称(比如RunRight)搜索目标动画剪辑swapSO_AnimationType

8)然后将animationClip 和 swapSO_AnimationType.animationClip的动画剪辑KeyValuePair<AnimationClip, AnimationClip>结构的animsKeyValuePairList中

9)通过aoc.ApplyOverrides让这些动画剪辑替换生效。

代码如下:

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

public class AnimationOverrides : MonoBehaviour
{
    [SerializeField] private GameObject character = null;
    [SerializeField] private SO_AnimationType[] soAnimationTypeArray = null;

    private Dictionary<AnimationClip, SO_AnimationType> animationTypeDictionaryByAnimation;
    private Dictionary<string, SO_AnimationType> animationTypeDictionaryByCompositeAttributeKey;

    private void Start()
    {
        // Initialise animation type dictionary keyed by animation clip
        animationTypeDictionaryByAnimation = new Dictionary<AnimationClip, SO_AnimationType>();

        foreach(SO_AnimationType item in soAnimationTypeArr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值