unity3d 射箭实现


用 iTween 抛物线 移动箭支

添加射箭动画事件

用 动画编辑器 添加事件
你选中FBX文件里的clip动画文件 
(比如你这个[email protected]里面的动画文件是那个Attack00) 
选中以后按CTRL+D 这样就把clip提取出来了 这才是可编辑的
把提取出来的clip拖到角色上 Animation组件上
选中角色
打开 菜单栏->Animation窗口 ->选择Preview下面按钮->选择动画片段->双击时间栏下面,弹出添加动画事件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 射箭代码 ,放在要射箭角色身上
/// </summary>
public class shootArrow : MonoBehaviour
{
    public GameObject arrowPrefab;//从面板手动赋值
    public Transform arrowShootPos;//从面板手动赋值
    public Transform enemyT;//从面板手动赋值

    public float arrowMoveSpeed = 10f;
    public float attackSpeed = 1f;

    public KeyCode keyCode =KeyCode.Q;

    UnitComponent uc;
    bool isInit = false;
    void Init()
    {
        if (false == isInit)
        {
            isInit = true;
            uc = GetComponent<UnitComponent>();
        }
    }


    //攻击动画 关键点 射出箭
    public void attackAnimtaionShootEvent()
    {
        shoot(arrowPrefab, arrowShootPos, enemyT.position, arrowMoveSpeed);
    }

    //攻击动画 关键点 射箭1轮结束
    public void attackAnimtaionOverEvent()
    {
        uc.animControl.SetState(AnimationType.idle);
    }


    void Update()
    {
        Init();
        if (Input.GetKeyDown(keyCode))
        {
            uc.anim["attack"].speed = this.attackSpeed;
            uc.animControl.SetState(AnimationType.attack);
        }
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="arrowPrefab">箭支预设物体</param>
    /// <param name="arrowShootPos">箭支发射位置和角度</param>
    /// <param name="enemyPos">目标位置</param>
    /// <param name="speed">速度</param>
    void shoot(GameObject arrowPrefab, Transform arrowShootPos,Vector3 enemyPos,float speed)
    {

        //抛物线
        Vector3[] paths = new Vector3[3];
        paths[0] = arrowShootPos.position;//第一个点:起始位置.

        Vector3 dir = (enemyPos - arrowShootPos.position).normalized;
        float distance = Mathf.Abs(Vector3.Distance(new Vector3(enemyPos.x, arrowShootPos.position.y, enemyPos.z), arrowShootPos.position));
        //第二个点:角色和目标的中间
        paths[1] = arrowShootPos.position + dir * (distance / 2f);//第二个点:起始位置前方几米处上方几米的坐标.
        paths[1].y = enemyPos.y + 0.25f;
        paths[2] = enemyPos;//终点,目标

        GameObject arrowObj = GameObject.Instantiate(arrowPrefab, arrowShootPos.position, arrowShootPos.rotation);
        iTween.MoveTo(arrowObj, iTween.Hash(
       "speed", speed,
       "path", paths,
        "looktarget", enemyPos
       ));
    }

}

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
/// <summary>
/// 单位组件 ,这个类获取组件用的
/// </summary>
public class UnitComponent : MonoBehaviour {


    public Animation anim;
    public NavMeshAgent agent;
    public AnimationControl animControl;
    // Use this for initialization
    void Start ()
    {
        GetAllComponents();
	}

    private void GetAllComponents()
    {
        anim = getComponentEx<Animation>("Animation");
        agent = getComponentEx<NavMeshAgent>("NavMeshAgent");
        animControl = getComponentEx<AnimationControl>("AnimationControl");
    }


    public T getComponentEx<T>(string ComponentName)
    {
        T t2 =GetComponent<T>();
        if(t2 == null)
        {
            Debug.LogError(gameObject.name + "ge Component" + ComponentName + "false");
            return default(T);
        }
        return t2;
    }

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

/// <summary>
/// 控制动画播放的
/// </summary>
public class AnimationControl : MonoBehaviour
{

    public AnimationType animationType = AnimationType.idle;

    UnitComponent uc;
    bool isInit = false;
    void Init()
    {
        if (false == isInit)
        {
            isInit = true;
            uc = GetComponent<UnitComponent>();
            uc.anim["free"].wrapMode = WrapMode.Loop;
            uc.anim["idle"].wrapMode = WrapMode.Loop;
            uc.anim["walk"].wrapMode = WrapMode.Loop;
            uc.anim["walk"].wrapMode = WrapMode.Loop;
            uc.anim["attack"].wrapMode = WrapMode.Once;
            uc.anim["death"].wrapMode = WrapMode.Once;
            uc.anim["skill"].wrapMode = WrapMode.Once;
        }
    }


    public void SetState(AnimationType animationType)
    {
        this.animationType= animationType;
        Init();
        switch (animationType)
        {
            case AnimationType.free:
                uc.anim.CrossFade("free");
                break;
            case AnimationType.idle:
                uc.anim.CrossFade("idle");
                break;
            case AnimationType.walk:
                uc.anim.CrossFade("walk");
                break;
            case AnimationType.run:
                uc.anim.CrossFade("run");
                break;
            case AnimationType.attack:
                uc.anim.CrossFade("attack");
                break;
            case AnimationType.skill:
                uc.anim.CrossFade("skill");
                break;
            case AnimationType.death:
                uc.anim.CrossFade("death");
                break;
        }
    }


}

public enum AnimationType
{
    free,
    idle,
    walk,
    run,
    attack,
    death,
    skill,
}








猜你喜欢

转载自blog.csdn.net/u013628121/article/details/79601775