• 【重要】攻击动作时间段判断~使用动画time比较动画length和使用一个变量数组做延迟


    using UnityEngine;
    
    using System.Linq;
    using System.Collections.Generic;
    
    [RequireComponent(typeof(CharacterMotor))]
    [RequireComponent(typeof(CharacterStatus))]
    [RequireComponent(typeof(CharacterAttack))]
    [RequireComponent(typeof(CharacterInventory))]
    
    public class CharacterSystem : MonoBehaviour
    {
        
        public float Speed    = 2; // Move speed
        public float SpeedAttack = 1.5f; // Attack speed
        public float TurnSpeed    = 5; // turning speed
    
        public float[] PoseAttackTime;// list of time damage marking using to sync with attack animation
        public string[] PoseAttackNames;// list of attack animation
        public string[] ComboAttackLists;// list of combo set
        
        public string[] PoseHitNames;// pose animation when character got hit
        public int WeaponType; // type of attacking
        public string PoseIdle = "Idle";
        public string PoseRun = "Run";
        public bool IsHero;
        
        
        
        
        //private variable
        private bool diddamaged;
        private int attackStep = 0;
        private string[] comboList;
        private int attackStack;
        private float attackStackTimeTemp;
        private float frozetime;
        private bool hited;
        private bool attacking;
        
    
        CharacterMotor motor;
        
        void Start()
        {
            motor = gameObject.GetComponent<CharacterMotor>();
            // Play pose Idle first
            gameObject.animation.CrossFade(PoseIdle);
            attacking = false;
        }
    
        
        void Update()
        {
            // Animation combo system
            
            if(ComboAttackLists.Length<=0){// if have no combo list
                return;
            }
            
            comboList = ComboAttackLists[WeaponType].Split(","[0]);// Get list of animation index from combolists split by WeaponType
            
            if(comboList.Length > attackStep){
                int poseIndex = int.Parse(comboList[attackStep]);// Read index of current animation from combo array
                if(poseIndex < PoseAttackNames.Length){    
                    // checking index of PoseAttackNames list
                    
                    AnimationState attackState = this.gameObject.animation[PoseAttackNames[poseIndex]]; // get animation PoseAttackNames[poseIndex]
                    attackState.layer = 2;
                    attackState.blendMode = AnimationBlendMode.Blend;
                    attackState.speed = SpeedAttack;
                    
                    if(attackState.time >= attackState.length * 0.1f){
                        // set attacking to True when time of attack animation is running to 10% of animation
                          attacking = true;    
                      }    
                       if(attackState.time >= PoseAttackTime[poseIndex]){
                        // if the time of attack animation is running to marking point (PoseAttackTime[poseIndex]) 
                        // calling CharacterAttack.cs to push a damage out
                          if(!diddamaged){
                            // push a damage out
                             this.gameObject.GetComponent<CharacterAttack>().DoDamage(); 
                          }
                    }
                    
                    if(attackState.time >= attackState.length * 0.8f){
                        // if the time of attack animation is running to 80% of animation. It's should be Finish this pose.
                        
                        attackState.normalizedTime = attackState.length;
                        diddamaged = true;
                        attacking = false;
                        attackStep += 1;
    
                        if(attackStack>1){
                            // checking if a calling attacking is stacked
                            fightAnimation();    
                        }else{
                            if(attackStep>=comboList.Length){
                                // finish combo and reset to idle pose
                                resetCombo();
                                  this.gameObject.animation.Play(PoseIdle);
                            }    
                        }
                        // reset character damage system
                        this.gameObject.GetComponent<CharacterAttack>().StartDamage();
                      }    
                }
            }
            
            if(hited){// Freeze when got hit
                if(frozetime>0){
                    frozetime--;    
                }else{
                    hited = false;
                    this.gameObject.animation.Play(PoseIdle);
                }
            }
            
            if(Time.time > attackStackTimeTemp+2){
                resetCombo();
            }
            
        }
        
        
        
        public void GotHit(float time){
            if(!IsHero){
                if(PoseHitNames.Length>0){
                    // play random Hit animation
                    this.gameObject.animation.Play(PoseHitNames[Random.Range(0,PoseHitNames.Length)], PlayMode.StopAll);
                }
                frozetime = time * Time.deltaTime;// froze time when got hit
                hited = true;
            }
        }
        
        private void resetCombo(){
            attackStep = 0;
            attackStack = 0;
            
        }
        
        private void fightAnimation(){
            
            attacking = false;
            if(attackStep>=comboList.Length){
                  resetCombo();    
            }
            
            int poseIndex = int.Parse(comboList[attackStep]);
            if(poseIndex < PoseAttackNames.Length){// checking poseIndex is must in the PoseAttackNames list.
                if(this.gameObject.GetComponent<CharacterAttack>()){
                    // Play Attack Animation 
                    this.gameObject.animation.Play(PoseAttackNames[poseIndex],PlayMode.StopAll);     
                }
                diddamaged = false;
            }
        }
        
        public void Attack()
        {    
            if(frozetime<=0){
                attackStackTimeTemp = Time.time;
                fightAnimation();
                attackStack+=1;
            }
            
        }
    
    
        
        
        public void Move(Vector3 dir){
            if(!attacking){
                moveDirection = dir;
            }else{
                moveDirection = dir/2f;    
            }
        }
        
        Vector3 direction;
        
        private Vector3 moveDirection
        {
            get { return direction; }
            set
            {
                direction = value;
                if(direction.magnitude > 0.1f)  
                {
                    var newRotation    = Quaternion.LookRotation(direction);
                    transform.rotation    = Quaternion.Slerp(transform.rotation,newRotation,Time.deltaTime * TurnSpeed);
                }
                direction *= Speed * 0.5f * (Vector3.Dot(gameObject.transform.forward,direction) + 1);
                    
                if(direction.magnitude > 0.001f)  
                {
                    // Play Runing Animation when moving
                    float speedaimation = direction.magnitude * 3;
                    gameObject.animation.CrossFade(PoseRun);
                    if(speedaimation<1){
                        speedaimation = 1;    
                    }
                    // Speed animation sync to Move Speed
                    gameObject.animation[PoseRun].speed    = speedaimation;
                
                }
                else{
                    // Play Idle Animation when stoped
                    gameObject.animation.CrossFade(PoseIdle);
                }
                if(motor){
                    motor.inputMoveDirection = direction;
                }
            }
        }
        
        
        
        float pushPower = 2.0f;
        void OnControllerColliderHit(ControllerColliderHit hit)// Character can push an object.
        {
            var body = hit.collider.attachedRigidbody;
            if(body == null || body.isKinematic){
                return;
            }
            if(hit.moveDirection.y < -0.3){
                return;
            }
            
            var pushDir = Vector3.Scale(hit.moveDirection,new Vector3(1,0,1));
            body.velocity = pushDir * pushPower;
        }
        
        
        
        
    }

    这段代码解决了我写配置表来控制动画攻击的问题 不需要用Time.time的变量来判断了

  • 相关阅读:
    uva10341
    android_定义多个Activity及跳转
    阿里巴巴2014年校园招聘(秋季招聘)在线笔试--測试研发project师
    关于程序猿的几个阶段!
    【Spring】Spring学习笔记-01-入门级实例
    感知器算法(二分类问题)
    Ubuntu14.04下安装ZendStudio10.6.1+SVN出现Failed to load JavaHL Library
    EF架构~关系表插入应该写在事务里,但不应该是分布式事务
    EF架构~在global.asax里写了一个异常跳转,不错!
    EF架构~为导航属性赋值时ToList()的替换方案
  • 原文地址:https://www.cnblogs.com/softimagewht/p/3880666.html
Copyright © 2020-2023  润新知