unity3d 代码 逐帧动画_unity帧动画代码控制第一帧的图片 - CSDN
  • Unity3d UGUI序列帧动画

    2019-07-21 23:27:19
    代码 using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.UI; using System; [RequireComponent(typeof(Image))] public class UGUISpriteAnimation : ...

    代码

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.UI;
    using System;
    
    [RequireComponent(typeof(Image))]
    public class UGUISpriteAnimation : MonoBehaviour
    {
    	private Image ImageSource;
    	private int mCurFrame = 0;
    	private float mDelta = 0;
    
    	public float FPS = 5;
    	public List<Sprite> SpriteFrames;
    	public bool IsPlaying = false;
    	public bool Foward = true;
    	public bool AutoPlay = false;
    	public bool Loop = false;
    
    	public int FrameCount
    	{
    		get
    		{
    			return SpriteFrames.Count;
    		}
    	}
    
    	void Awake()
    	{
    		ImageSource = GetComponent<Image>();
    	}
    
    	void Start()
    	{
    		if (AutoPlay)
    		{
    			Play();
    		}
    		else
    		{
    			IsPlaying = false;
    		}
    	}
    
    	private void SetSprite(int idx)
    	{
    		ImageSource.sprite = SpriteFrames[idx];
    		ImageSource.SetNativeSize();
    	}
    
    	public void Play()
    	{
    		IsPlaying = true;
    		Foward = true;
    	}
    
    	public void PlayReverse()
    	{
    		IsPlaying = true;
    		Foward = false;
    	}
    
    	void Update()
    	{
    		if (!IsPlaying || 0 == FrameCount)
    		{
    			return;
    		}
    
    		mDelta += Time.deltaTime;
    		if (mDelta > 1 / FPS)
    		{
    			mDelta = 0;
    			if(Foward)
    			{
    				mCurFrame++;
    			}
    			else
    			{
    				mCurFrame--;
    			}
    
    			if (mCurFrame >= FrameCount)
    			{
    				if (Loop)
    				{
    					mCurFrame = 0;
    				}
    				else
    				{
    					IsPlaying = false;
    					return;
    				}
    			}
    			else if (mCurFrame<0)
    			{
    				if (Loop)
    				{
    					mCurFrame = FrameCount-1;
    				}
    				else
    				{
    					IsPlaying = false;
    					return;
    				}			
    			}
    			
    			SetSprite(mCurFrame);
    		}
    	}
    
    	public void Pause()
    	{
    		IsPlaying = false;
    	}
    
    	public void Resume()
    	{
    		if (!IsPlaying)
    		{
    			IsPlaying = true;
    		}
    	}
    
    	public void Stop()
    	{
    		mCurFrame = 0;
    		SetSprite(mCurFrame);
    		IsPlaying = false;
    	}
    
    	public void Rewind()
    	{
    		mCurFrame = 0;
    		SetSprite(mCurFrame);
    		Play();
    	}
    }
    

      

    转载于:https://www.cnblogs.com/mrblue/p/5191183.html

    展开全文
  • 博主今天想和大家分享的是在Unity3D中使用...相信在大家的印象中,Mecanim动画系统主要运用在3D动画中,因为Mecanim动画系统提供了像动画重定向、人体骨骼动画等3D动画的特性,那么Unity3D的Mecanim动画系统能不能

    各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是http://blog.csdn.net/qinyuanpei。博主今天想和大家分享的是在Unity3D中使用Mecanim动画系统来控制2D动画。相信在大家的印象中,Mecanim动画系统主要运用在3D动画中,因为Mecanim动画系统提供了像动画重定向、人体骨骼动画等3D动画的特性,那么Unity3D的Mecanim动画系统能不能用来控制2D动画呢?如果在以前,博主和大家的理解是一样的,认为Mecanim只能运用到3D动画中,对于2D动画只能使用传统的逐帧动画和骨骼动画。可是前不久有位朋友问我,为什么不使用动画组件来控制2D动画呢?博主心想啊,这Mecanim动画系统真的能控制2D动画吗?经过博主查找大量资料和亲身实践,发现Mecanim是可以用来控制2D动画的,而且由于状态机的引入,我们对动画状态的控制会变得更为简单,从写代码的角度来看,这样可以减少我们的代码量便于维护。那么好了,今天我们就来一起学习下如何使用Mecanim动画系统来控制2D动画吧!

    传统2D动画的实现方式

    在Unity3D中传统2D动画的实现方式是基于逐帧动画的原理实现的,这种实现方式在Unity3D没有推出Unity2D前甚至在Unity2D推出后相当长的一段时间内,基本上我们最为常用的实现方式,博主在刚开始学习Unity3D的时候通常是以2D形式来展开的,因为博主认为2D和3D在原理上基本是相通的,如果我们掌握了2D游戏的基本原理,那么在实现3D游戏的时候就会相对容易些。我们来看看一个最简单的2D动画的脚本实现:

    //精灵渲染器
    private SpriteRenderer mRenderer;
    //精灵集合
    public Sprite[] Sprites;
    //FPS,即每秒钟的画面帧数
    public float FPS = 24;
    //精灵索引
    private int index = 0;
    //当前时间
    private float currentTime = 0;
    
    void Start () 
    {
        mRenderer = GetComponent<SpriteRenderer>();
    }
    
    void Update () 
    {
        //获取当前时间
        currentTime += Time.deltaTime;
        //如果达到了更新画面的时间
        if(currentTime >= 1 / FPS)
        {
            //使索引增加
            index += 1;
            //清除时间记录
            currentTime = 0;
            //当索引更新到最后一帧时,索引重置
            if(index >= Sprites.Length)
            {
                index = 0;
            }
        }
    
        //更新画面
        mRenderer.sprite = Sprites[index];
    }
    

    通过分析,我们可以发现这段脚本存在以下问题:
    * 动画维护困难:每增加一个动画就需要添加一个数组,不仅增加了动画的维护难度,同时降低了脚本的效率。
    * 状态维护困难:因为在Update方法里实现的是一个动画,因此当我们需要在各个动画状态间进行切换的时候,我们需要使用更多的代码来维护相关逻辑。

    使用Mecanim动画系统的实现方式

    为了解决传统的2D动画实现方式中存在的动画维护困难、状态维护困难这两个问题,我们需要一种更好的方案来实现2D动画的控制,这种方案需要提供较为方便的动画维护功能,即各个动画是独立的,当改变了某一个动画时,其余的动画不会发生改变。其次,这种方案需要提供较为方便的状态维护功能,即各个动画状态切换是方便的,我们可以更好地从这一种状态切换到另一种状态。关于动画状态切换,大家可以去了解下有限状态机(FSM)的概念,这里我们不做深入的探究,这里我们选择Unity3D的Mecanim动画系统,因为Mecanim动画系统正好解决了这两个问题。好了,下面我们来一起学习一个2D动画的实例:
    首先我们在场景中创建一个名为PlayerController的空物体,然后在该物体的下面增加一个精灵组件(Sprite),并将其命名为PlayerSprite,这样做的好处是Unity3D将为我们自动创建较为规范的命名。好了,现在我们选择PlayerController这个物体,然后通过Window->Animation菜单打开Animation窗口:
    Animation窗口

    首先我们点击AddCurve按钮,此时将弹出一个对话框让我们保存动画文件,这里我们存储为Player@Idle.anim,并将其保存在项目目录下的Animations\Player目录下,这样可以方便我们维护和查找特定的动画文件。在保存完动画文件后,此时会弹出如下的界面,我们选择PlayerSprite节点下的SpriteRenderer,然后选择Sprite,因为这里我们的2D动画主要是通过改变SpriteRenderer的Sprite属性来实现的,最后我们点击Sprite节点后面的加号来完成对象的选取。此时会在动画窗口中显示时间轴和刻度线,我们将在这里完成动画的编辑。大家可以注意到默认情况下,动画面板添加了两帧,即第1帧和最后一帧,其总时间是1秒,同时我们注意到这里有一个采样率(Sample),其实这就是当前动画的FPS了。好了,现在我们开始制作第一个动画:

    制作第一个动画

    在资源文件夹中,我们可以找到当前动画的图片素材,注意到这个图片中总共有12帧画面,因此我们可以按照0.05s的间隔来分配整个时间轴,所以我们可以这样添加帧:

    帧动画序列

    好了,现在我们就完成了一个Idle动画的制作,现在打开角色的动画控制器PlayerController,这是Unity3D为我们自动创建的一个动画控制器,因为我们现在只有一个Idle动画,所以在Animaotr窗口中我们可以看到只有一个Idle状态,现在我们将这个状态设为默认状态。好了,现在我们可以直接运行游戏,发现在场景中角色开始循环播放Idle动画了。好了,现在让我们重复刚才的步骤,来完成角色的其余动画。

    Idle动画

    经过一番努力,我们现在已经完成了角色所有动画的制作,现在我们来设计角色的动画状态机:

    状态机设计

    设计好角色的动画状态机后我们开始来编写脚本,以实现角色动画的控制:

    using UnityEngine;
    using System.Collections;
    
    public class PlayerController : MonoBehaviour {
    
        public enum PlayerState
        {
            Idle,
            Move,
            LightAttack,
            WeightAttack
        }
    
        public PlayerState State=PlayerState.Idle;
        //玩家移动速度
        public float WalkSpeed = 0.75f;
        public float RunSpeed = 1.5f;
        //玩家跳跃力的强度
        public float JumpForce = 200f;
    
        //位置限制
        public float MinX = -5.80f;
        public float MaxX =  5.80f;
        public float MinY = -1.80f;
        public float MaxY =  0.35f;
    
        //玩家朝向,默认朝右
        public bool isFaceRight = true;
    
        //动画组件
        private Animator mAnim;
        //2D刚体
        private Rigidbody2D mRig2D;
    
    
        void Start () 
        {
            mAnim=GetComponent<Animator>();
            mRig2D=GetComponent<Rigidbody2D>();
        }
    
        void Update()
        {
            SpriteMove();
            SpriteAttack();
            SpriteJump();
            SpriteIdle();
        }
    
        /// <summary>
        /// 精灵Idle
        /// </summary>
        private void SpriteIdle()
        {
            //当玩家无任何操作时恢复到Idle状态
            if (!Input.anyKey)
            {
                mAnim.SetBool("Jump", false);
                mAnim.SetBool("Attack", false);
                mAnim.SetBool("BigAttack", false);
                mAnim.SetBool("Skill", false);
                mAnim.SetBool("BigSkill", false);
                State=PlayerState.Idle;
            }
        }
    
        /// <summary>
        /// 精灵攻击
        /// </summary>
        private void SpriteAttack()
        {
            //轻击,键位J
            if(Input.GetKey(KeyCode.J))
            {
                mAnim.SetBool("Attack", true);
                State=PlayerState.LightAttack;
            }
    
            //重击,键位K
            if(Input.GetKey(KeyCode.K))
            {
                mAnim.SetBool("BigAttack", true);
                State=PlayerState.WeightAttack;
            }
    
        }
    
        /// <summary>
        /// 精灵跳跃
        /// </summary>
        private void SpriteJump()
        {
            if (Input.GetKey(KeyCode.I))
            {
                mAnim.SetBool("Jump", true);
                mRig2D.AddForce(new Vector2(0, Time.deltaTime * JumpForce), ForceMode2D.Impulse);
            }
        }
    
        private void SpriteMove()
        {
            float h = Input.GetAxis("Horizontal");
            float v = Input.GetAxis("Vertical");
    
            Vector2 mPos = mRig2D.position;
    
            mAnim.SetFloat("Speed", Mathf.Sqrt(h * h + v * v));
    
            float mPosX, mPosY;
    
            if (Mathf.Sqrt(h * h + v * v) > 0.5f){
                mPosX = mPos.x + h * Time.deltaTime * RunSpeed;
                mPosY = mPos.y + v * Time.deltaTime * RunSpeed;
            }else{
                mPosX = mPos.x + h * Time.deltaTime * WalkSpeed;
                mPosY = mPos.y + v * Time.deltaTime * WalkSpeed;
            }
    
    
            mRig2D.MovePosition(new Vector2(mPosX, mPosY));
    
            if (h > 0 && !isFaceRight)
            {
                FlipSrite();
            }
            else if (h < 0 && isFaceRight)
            {
                FlipSrite();
            }
        }
    
    
        void FlipSrite()
        {
            if(isFaceRight){
                transform.rotation=Quaternion.Euler(0,180,0);
                isFaceRight=false;
            }else{
                transform.rotation=Quaternion.Euler(0,0,0);
                isFaceRight=true;
            }
        }
    }
    

    好了,现在我们可以来看看最终的效果,博主这里是想利用这些素材来制作一个横板过关的游戏,可是因为文章篇幅有限,所以这部分内容只能留到以后再和大家分享了。

    最终效果

    Mecanim动画系统应用扩展

    好了,到现在为止,基于Mecanim动画系统的2D动画控制基本上讲解完了。下面我们说说Mecaanim动画系统应用扩展。通过前面的学习,我们知道Unity2D使用的Mecanim动画系统主要是通过改变游戏体的属性来实现某种特定的动画效果的,例如我们这里的动画是通过改变角色精灵附加的SpriteRenderer组件的Sprite属性来实现的,因此从本质上来说Unity2D的动画控制器是一种属性动画。总体来说,Unity2D可以实现以下类型的动画:
    * 位移动画:通过Transform组件的Position属性实现
    * 旋转动画:通过Transform组件的Rotation属性实现
    * 伸缩动画:通过Transform组件的Scale属性实现
    * 渐变动画:通过更改指定组件的颜色或材质实现
    * 脚本动画:通过更改指定脚本的变量或字段实现

    好了,这就是今天这篇文章的全部内容了,希望大家喜欢!

    展开全文
  • 帧动画(Frame By Frame)的原理 关键是连续的关键帧分解动作,也就是在时间轴的每帧上帧绘制不同的内容,使其连续播放而成动画。虽然每一帧都不一样,处理的信息量大,但是,帧动画具有非常大的灵活性,几乎可以...

    帧动画(Frame By Frame)的原理

    链接: 项目实例资源
    关键是连续的关键帧分解动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。虽然每一帧都不一样,处理的信息量大,但是,帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容,很适合于表演细腻的动画。例如:人物或动物急剧转身、 头发及衣服的飘动、走路、说话以及精致的3D效果等等。

    在2D游戏中实现帧动画的方式

    在Canvas下创建一个Image节点,图片要是Sprite (2D and UI)
    在这个节点下加上一个C#脚本
    在脚本里实现图片的播放
    

    脚本代码

    [RequireComponent(typeof(Image))] 当前代码强制要求加入一个Image组件或者其他的组件,需要在代码中加入这一行代码,如果节点上有这个组件就使用,如果没有就创建。
    
    //名字空间
    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    
    //当前代码强制要求加入一个Image组件,如果没有Image组件,那么就自动加上
    //如果有就使用
    [RequireComponent(typeof(Image))]
    public class frame_anim : MonoBehaviour {
        //帧动画所需要的画面
        public Sprite[] sprite_frame;
        //帧动画的时间间隔
        public float duration = 0.1f;
        //是否循环播放
        public bool is_loop = false;
        //是否在加载时播放
        public bool play_onload = false;
    
        private float played_time; //过去的时间
        private bool is_playing = false;
        private Image img;  //时间间隔一到需要播放的图片
        //private bool loop = false;
    	// Use this for initialization
    	void Start () {
    		//获取此节点上的Image组件
            this.img = this.transform.GetComponent<Image>();
            if (this.play_onload)  //判断是否在加载时播放
            {
                if (this.is_loop)  //判断播放方式
                {
                    this.play_loop();
                }
                else
                {
                    this.play_once();
                }
            }
        } 
        //只播放一次
        void play_once()
        {
            if (this.sprite_frame.Length <= 1) return;
            this.played_time = 0;
            this.is_playing = true;
            this.is_loop = false;
    
        }
       //循环播放
        void play_loop()
        {
            if (this.sprite_frame.Length <= 1) return;
            this.played_time = 0;
            this.is_playing = true;
            this.is_loop = true;
            
    
        }
        //停止播放
        void stop_play()
        {
            this.is_playing = false;
        }
    	// Update is called once per frame
    	void Update () {
            if (this.is_playing == false)
            {
                return;
    
            }
            float dt = Time.deltaTime;
            this.played_time += dt;  
            //向下取整
            int index = (int)(this.played_time / this.duration);//需要播放画面的下标
    
            //是否循环播放
            if (this.is_loop == false)  
            {
                if (index >= this.sprite_frame.Length)  //停止播放
                {
                    this.is_playing = false;
                    this.played_time = 0;
                }else
                {
                    this.img.sprite = this.sprite_frame[index];
                }
            }
            //播放一次
            else
            {
                //while (index >= this.sprite_frame.Length)
                //{
                    //this.played_time -= (this.duration * this.sprite_frame.Length);
                    index %= this.sprite_frame.Length;
                //}
                this.img.sprite = this.sprite_frame[index];
            }
    	}
    }
    

    图片下标设置

    Unity3d编辑器里设置每一帧的图片

    帧动画

    Size 为播放图片的数组大小 Element0~size-1 为每一帧的图片
    展开全文
  • Unity3D之简单的帧动画 代码 博文地址:http://blog.csdn.net/midashao/article/details/8139109
  • unity3d播放序列帧动画

    千次阅读 2017-06-27 09:53:19
    这里的播放序列帧动画不仅仅是UGUI,我使用的是创建在3d的物体plane上面。 代码如下 using System.Collections; using System.Collections.Generic; using UnityEngine; public class ChangeTexture : ...

    这里的播放序列帧动画不仅仅是UGUI,我使用的是创建在3d的物体plane上面。

    代码如下

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ChangeTexture : MonoBehaviour {
        //texture贴图变量
        [SerializeField]
        private Texture ImageAmi;
        //计数器
        [SerializeField]
        private int _countImageNumber = 138;
        //当前时间
        private float _currentTime = 0f;
        //每帧间隔时间
        [SerializeField]
        private float IntervalTime = 3.0f;
        //贴图文件名
        private string _leftTextureName = "Image/A021212315";
        //贴图名字
        public string _myTextureName;
        //起始帧
        public int _myStartFrame = 0000;
        //帧间隔
        public int _myOffsetFrame = 1;
        //当前帧
        private int _currentFrame = 0;
        
    	// Use this for initialization
    	void Start () {
            _countImageNumber = 0;
            this.GetComponent<Renderer>().material.mainTexture = ImageAmi;
        }
    	
    	// Update is called once per frame
    	 void Update () {
             
                if (_currentFrame < 136)
                {
                    LeftLoadImage();
                    _currentFrame++;
                }
                else
                {
                    _countImageNumber = 0;
                    _currentFrame = 0;
                }
    
        }
        //顺序加载图片
        void LeftLoadImage() {
    
            string _rightTextureName = string.Format("{0:D4}", _currentFrame);
            _myTextureName = _leftTextureName + _rightTextureName;
            Texture ImgAmi = (Texture)Resources.Load(_myTextureName);
            this.GetComponent<Renderer>().material.mainTexture = ImgAmi;
            
        }
    }
    使用的方法是将顺序的序列帧放在resources文件下的image中,然后通过字符串拼接,每次加载一张序列帧,通过顺序加载来达到播放动画的效果。因为我是在plane上使用的,所以是将获取到的贴图赋予到物体的材质贴图上的。至于具体的播放间隔时间,可以自己设置,我是直接使用的update的更新速率,但是在命名是也考虑了怎么调整播放间隔,不过因为update的速率满足了我的需求所以没有再自己写。

    除了上面的简单方案,还可以通过加入倒序播放,然后再加上一个按钮按下播放,松开停止播放,来实现一个伪3d操控效果。

    展开全文
  • Unity3D开发之制作序列帧动画

    万次阅读 2018-05-08 09:08:15
    动画机 unity自带的帧动画机很方便,我们首先选择所要播放序列帧动画的Image,然后在Window下选择Animation,会弹出一个动画制动的界面,我们选择Create,然后进入如下界面:我们按照如下添加动画控制的属性,然后...
  • Unity——用代码实现序列帧动画

    千次阅读 2018-10-25 18:44:21
    序列帧动画经常用到,最...但某些情况下这种方式并不是太友好,需要靠代码的方式进行序列帧动画的实现。 代码实现序列帧动画,基本的思路是定义一个序列帧的数组/列表,根据时间的流逝来确定使用哪一帧并更新显示。
  • 前些日子公司让笔者写了一个帧动画控制工具,主要是用来控制聊天表情这些2D动画的,原本想偷懒在网上直接考了一份代码,没想到运行之后发现当帧率为负的时候还有bug,最后在他基础上做了改动,优化了一下并把bug修复...
  • Unity3D代码中切割图片并且加载序列动画 在Cocos2dx中,对大图的处理已经封装好了一套自己的API,但是在Unity3D中貌似没有类似的API,或者说我没找到。不过这也在情理之中,毕竟Unity3D是做3D的,要切割图片的...
  • 如何在unity中创建2D帧动画

    千次阅读 2018-11-16 16:26:45
    我们都知道unity中支持我们创建简单的3D动画,实现起来也非常的简单,但其实在我们创建2D项目时,也可以通过unity创建简单的2D帧动画。  首先我们说什么时帧动画,说白了原理就像我们小时候玩过的“动画小人书”,...
  • Unity3d的序列帧动画

    2019-08-04 05:33:58
    最近项目中用到了很多序列帧动画,之前看教程也接触过序列帧动画,但当时没用到,就没仔细研究,这次就借着这个机会好好总结一下序列帧动画。 思路 序列帧动画的原理很好理解,首先必须要有一个载体,一般是一个...
  • Unity3D中播放序列帧动画

    千次阅读 2015-03-11 21:10:51
    【狗刨学习网】 class FrameAnimation  {  private float fps = 10.0f;  private Rect drawPos;  private float time = 0;... private int currentIndex = 0;... public void DrawFrameAnimation(T
  • unity3d播放帧动画

    2016-09-12 11:47:56
    unity3d如何播放帧动画,我写的这种方法比较麻烦。得一张一张图片的往数组里拖,适合图片较少的帧动画。 效果如下: 上代码吧: using UnityEngine; using System.Collections; public class play : ...
  • 项目开发遇到问题:要将unitypackage里的3D动画改成2D帧动画
  • using UnityEngine; public class SpriteAnimator : ... /// Sprite动画帧 public Sprite[] m_clips; /// 动画计时器(默认每隔0.1秒更新一) protected float timer = 0.1f; /// 当前的数 prote.
  • Unity3D Shader示例之UI序列帧动画

    千次阅读 2018-04-27 11:40:31
    最近在做一个富文本插件YLYRichText,里面用到了ui动画表情,效果如下:其原理是在shader里面按照一定的速度改变uv,按顺序计算每一的uv偏移量和宽高比例,抓取序列图片里面每一的区域渲染出来。代码里面有...
  • 最近想做一个动画的分步播放,但是在实现动画复位时发现以前用的动画复位的代码不起作用了: @Animation = AnimationObj.GetComponent<Animation>(); AniState = @Animation[ClipName]; AniState.time = 0; @...
  • unity3d动画操作以及动画实现

    万次阅读 2015-03-11 20:29:58
    今天主要总结的是 unity3d 中内置动画操作,以及代码事件编写动画实现 1.如何导入、执行外部动画  在项目窗口中,首先,单击选择我们所准备的动画模型,在属性面板中选择Animations栏, 在属性中点击“+","-"可以...
  • unity帧动画的几种方式比较

    千次阅读 2017-01-02 17:04:58
    之前一直没有做帧动画系列,以前的动画方式多是用程序控制,或者有些效果类型的会用shader实现。但后面要加各种特效动画,就必须熟悉帧动画了。 看了好多关于帧动画方面的思路,感觉方式还是很多的,但到底哪个好,...
  • 本小主在这里给大家分享一下unity 2D游戏开发中制作帧动画的两种方法。 比较简单,一学即会。 方法一: 是用代码控制: 先创建一个2D工程。导入图片资源,并设置texture的texture type为sprite,看下图...
1 2 3 4 5 ... 20
收藏数 4,010
精华内容 1,604
关键字:

unity3d 代码 逐帧动画