原文链接: https://blog.csdn.net/pigautumn/article/details/81781403

需求场景:由若干个数量不确定的物体从上到下排列,需要间隔0.1s依次从左到右移动到某个位置,然后返回一小段距离。

分析:使用Unity3D的动画系统很容易实现这个功能,但是物体数量不确定,考虑将其绑定到同一个物体下,为这个物体动态创建Animation、AnimationClip(一个Animation可以含有多个动作,即AnimationClip,但我们只需要一个动作),然后针对各个子物体创建不同的AnimationCurve,最后调用这个Animation,即可实现各个物体先后按照设定的移动动画进行运动。

代码:

class testAnim
{
private Animation _animation = null;

public GameObject Target = null; //目标对象
public GameObject[] Items = null; //目标对象子对象数组
public float[] PosY = null; //目标对象子对象的Y坐标

public float AnimDuration = 0.3f; //动画所用时间
public float AnimBackTime = 0.1f; //动画返回所用时间
public float AnimInterval = 0.1f; //相邻物体间动画间隔
public float InitXPos = -25; //X坐标初始化位置
public float MaxXPos = 90; //X坐标最大位置
public float DestXPos = 60; //X坐标目标位置

// Use this for initialization
void Start()
{
if (Target == null || Items == null || Items.Length <= 0 || Items.Length != PosY.Length)
{
return;
}

_animation = Target.AddComponent<Animation>();

var clip = new AnimationClip()
{
name = "test",
legacy = true,
wrapMode = WrapMode.Once
};

for (var i = 0; i < Items.Length; i++)
{
var item = Items[i];
if (item == null)
{
continue;
}

var relativePath = item.name;

//创建X轴动画
var curve = new AnimationCurve();
curve.AddKey(new Keyframe(0, InitXPos)); //初始状态
curve.AddKey(new Keyframe(0 + AnimInterval * i, InitXPos)); //暂停关键帧
curve.AddKey(new Keyframe(0 + AnimInterval * i + AnimDuration, MaxXPos)); //运动关键帧
curve.AddKey(new Keyframe(AnimInterval * i + AnimDuration + AnimBackTime, DestXPos)); //返回关键帧
clip.SetCurve(relativePath, typeof(RectTransform), "m_AnchoredPosition.x", curve);

//创建Y轴动画
curve = new AnimationCurve();
curve.AddKey(new Keyframe(0, PosY[i]));
curve.AddKey(new Keyframe(AnimDuration + AnimInterval * i, PosY[i]));
clip.SetCurve(relativePath, typeof(RectTransform), "m_AnchoredPosition.y", curve);

//创建Scale动画
curve = new AnimationCurve();
curve.AddKey(new Keyframe(0, 0)); //初始状态
curve.AddKey(new Keyframe(0 + AnimInterval * i, 0)); //暂停状态
curve.AddKey(new Keyframe(AnimInterval * i + AnimDuration, 1)); //运动状态
clip.SetCurve(relativePath, typeof(RectTransform), "m_Scale.x", curve);
clip.SetCurve(relativePath, typeof(RectTransform), "m_Scale.y", curve);
}

_animation.AddClip(clip, clip.name);
_animation.Play(clip.name);
}
}
Points:

(1)每个动画(Animation)可以包含多个片段(AnimationClip),这里只需要一个;

(2)每个片段包含多条曲线(AnimationCurve),每条曲线描述了哪个物体(relativePath)的哪个属性(例如RectTransform的m_AnchoredPosition.x,表示锚点位置X轴的变化)怎么运动;

(3)每个动作曲线(AnimationCurve)含有多个关键帧(Keyframe),表示运动的变化情况,例如X轴坐标从(0秒,位置0)移动到(0.3s,位置90),再移动到(0.4s,位置60);

(4)重要的一点是,在描述例如RectTransform类型的属性时,需要使用“m_AnchoredPosition.x”的形式,参考“解决AnimationClip.SetCurve RectTransform Color参数 出现Missing!的情况”。
---------------------
作者:xhubobo
来源:CSDN
原文:https://blog.csdn.net/pigautumn/article/details/81781403
版权声明:本文为博主原创文章,转载请附上博文链接!

Unity3D使用脚本动态创建、调用动画(转)的更多相关文章

  1. JS,Jquery,ExtJs不同脚本动态创建DOM对象

    好久不来写东西了,这段时间太慢了,闲了下来看了几篇文章,觉得很好,同时也许咱们大家都能遇到,所以就把它记录下来... 简单使用JavaScript.JQuery.ExtJs进行DOM对象创建的测试,主 ...

  2. unity3d通过代码动态创建销毁游戏对象

    只能动态创建内部提供的游戏对象,代码如下: //按下C后创建 if (Input.GetKeyDown (KeyCode.C)) { GameObject s1 = GameObject.Create ...

  3. ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段

    ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...

  4. CXF 动态创建客户端调用稳定版本号为2.7.18

    今天用动态创建客户端的方式调用webservice,报了这样一个错: 2017-01-05 20:51:46,029 DEBUG main org.apache.cxf.common.logging. ...

  5. javascript动态创建script标签,加载完成后调用回调

    代码如下: var head = document.getElementsByTagName('head')[0]; var script = document.createElement('scri ...

  6. CXF 调用方式——动态创建客户端(调用稳定版本号为2.7.18)

    今天用动态创建客户端的方式调用webservice,报了这样一个错: 2017-01-05 20:51:46,029 DEBUG main org.apache.cxf.common.logging. ...

  7. WCF 动态调用(动态创建实例接口)

    很多时候,服务地址都不止一个的,这个时候就要动态去配置地址.配置Web.config,很麻烦 下面就看看怎样实现动态调用WCF. 首先看看动态创建服务对象的代码: using System; usin ...

  8. document基本操作 动态脚本-动态样式-创建表格

    var html = document.documentElement; var body = document.body; window.onload = function() { //docume ...

  9. ? 原创: 铲子哥 搜狗测试 今天 shell编程的时候,往往不会把所有功能都写在一个脚本中,这样不太好维护,需要多个脚本文件协同工作。那么问题来了,在一个脚本中怎么调用其他的脚本呢?有三种方式,分别是fork、source和exec。 1. fork 即通过sh 脚本名进行执行脚本的方式。下面通过一个简单的例子来讲解下它的特性。 创建father.sh,内容如下: #!/bin/bas

    ? 原创: 铲子哥 搜狗测试 今天 shell编程的时候,往往不会把所有功能都写在一个脚本中,这样不太好维护,需要多个脚本文件协同工作.那么问题来了,在一个脚本中怎么调用其他的脚本呢?有三种方式,分别 ...

  10. C#反射动态创建实例并调用方法

    在.Net 中,程序集(Assembly)中保存了元数据(MetaData)信息,因此就可以通过分析元数据来获取程序集中的内容,比如类,方法,属性等,这大大方便了在运行时去动态创建实例. MSDN解释 ...

随机推荐

  1. [Unity]Update()与FixedUpdate()

    Update()介绍 首先我们从官方文档的介绍了解: MonoBehaviour.Update() Description Update is called every frame, if the M ...

  2. 基于WebSocket的实时消息传递设计

    目录 概述 整体架构 设计 流程设计 程序设计 WebSocketServer 概述 新增pom 新增配置类 创建websocket端点 WebSocketClient 概述 安装WebSocketS ...

  3. angular组件共用服务打印日志父子组件传值2创建服务注入

  4. NLP知识图谱项目合集(信息抽取、文本分类、图神经网络、性能优化等)

    NLP知识图谱项目合集(信息抽取.文本分类.图神经网络.性能优化等) 这段时间完成了很多大大小小的小项目,现在做一个整体归纳方便学习和收藏,有利于持续学习. 1. 信息抽取项目合集 1.PaddleN ...

  5. 我为什么要放弃RESTful,选择拥抱GraphQL

    背景 REST作为一种现代网络应用非常流行的软件架构风格,自从Roy Fielding博士在2000年他的博士论文中提出来到现在已经有了20年的历史.它的简单易用性,可扩展性,伸缩性受到广大Web开发 ...

  6. C++迭代器种类与编译期间多态

    迭代器分类 C++ STL 中根据移动能力将迭代器分成了 5 类: Input Iterator 输入迭代器,只支持 operator++ 操作. Output Iterator 输出迭代器,只支持 ...

  7. Vue 3项目如何设置全局变量

  8. @RestControllerAdvice全局异常统一处理

    spring项目中,我们通常规定了返回的格式(成功-失败-异常),特别是异常怎么处理方便呢? 1.自定义状态码实体 package com.ruoyi.common.constant; /** * 返 ...

  9. Listary 文件搜索工具

    Listary简介 Listary是一款强大的全盘文件搜索.软件启动效率工具,双击Ctrl随时调出搜索框,全盘海量文件毫秒级检索,快速定位打开所需文件.集成右键菜单和诸多自定义动作,适配Windows ...

  10. Opengl ES之踩坑记

    前因 最近在尝试使用Opengl ES实现一些LUT滤镜效果,在实现这些滤镜效果的时候遇到一些兼容性的坑,踩过这些坑后我希望把这几个坑分享给读者朋友们, 希望同在学习Opengl ES的朋友们能少走弯 ...