Unity实现杀戮尖塔出牌效果(一.扇形开牌)

最终效果展示

主要步骤

一. 扇形开牌

二. 鼠标指向卡牌时,卡牌强调动画

①卡牌高度提升
②卡牌旋转归零
③卡牌层级高于其他手牌

三. 卡牌使用效果

1. 攻击类型卡牌

①拖拽超过一定高度之后卡牌会移动到手牌中心位置
②出现攻击引导箭头
③成功指向目标怪物后打出

2. 技能能力类型卡牌

①可自由拖动
②脱离手牌高度后打出

四. 卡牌使用结束效果

1. 播放攻击特效

2. 播放卡牌收尾特效

①卡牌从当前位置移动到中心位置
②卡牌居中悬停展示几毫秒
③播放回归弃牌堆动画

代码详解

一. 扇形开牌

在这里插入图片描述

核心代码

public class CardItem : MonoBehaviour  
{  
    /// <summary>  
    /// 卡牌扇形展开中心点  
    /// </summary>  
    public Vector3 root;  
    /// <summary>  
    /// 展开角度  
    /// </summary>  
    public float rot;  
    /// <summary>  
    /// 展开半径  
    /// </summary>  
    public float size;  
    /// <summary>  
    /// 动画速度  
    /// </summary>  
    public float animSpeed = 10;  
    /// <summary>  
    /// 高度值(决定卡牌层级)  
    /// </summary>  
    public float zPos=0;  
  
  
    public  void RefreshData(Vector3 root,float rot, float size,float zPos)  
    {        
        this.root = root;  
        this.rot = rot;  
        this.size = size;  
        this.zPos = -zPos*0.02f;  
    }  
    // Update is called once per frame  
    void Update()  
    {        
        SetPos();  
    }  
    public void SetPos()  
    {        
        //设置卡牌位置  
        float x = root.x + Mathf.Cos(rot) * size;  
        float y = root.y + Mathf.Sin(rot) * size;  
        transform.position = Vector3.Lerp(transform.position, new Vector3(x, y, root.z+this.zPos), Time.deltaTime * animSpeed);  
        //设置卡牌角度  
        float rotZ = GetAngleInDegrees(root, transform.position);  
        Vector3 localEulerAngles = transform.localEulerAngles;  
        Quaternion rotationQuaternion = Quaternion.Euler(new Vector3(0, 0, rotZ));  
        transform.rotation = Quaternion.RotateTowards(transform.rotation, rotationQuaternion, Time.deltaTime * animSpeed * 30);  
    }    
    /// <summary>  
    /// 获取两个向量之间的弧度值0-2π  
    /// </summary>    /// <param name="positionA">点A坐标</param>  
    /// <param name="positionB">点B坐标</param>  
    /// <returns></returns>    
    public static float GetAngleInDegrees(Vector3 positionA, Vector3 positionB)  
    {        
        // 计算从A指向B的向量  
        Vector3 direction = positionB - positionA;  
        // 将向量标准化  
        Vector3 normalizedDirection = direction.normalized;  
        // 计算夹角的弧度值  
        float dotProduct = Vector3.Dot(normalizedDirection, Vector3.up);  
        float angleInRadians = Mathf.Acos(dotProduct);  
  
        //判断夹角的方向:通过计算一个参考向量与两个物体之间的叉乘,可以确定夹角是顺时针还是逆时针方向。这将帮助我们将夹角的范围扩展到0到360度。  
        Vector3 cross = Vector3.Cross(normalizedDirection, Vector3.up);  
        if (cross.z > 0)  
        {            
           angleInRadians = 2 * Mathf.PI - angleInRadians;  
        }  
        // 将弧度值转换为角度值  
        float angleInDegrees = angleInRadians * Mathf.Rad2Deg;  
        return angleInDegrees;  
    }}
public class CardManager : MonoBehaviour  
{  
    /// <summary>  
    /// 卡牌起始位置  
    /// </summary>  
    public Vector3 rootPos=new Vector3(0,-33.5f,20);  
    /// <summary>  
    /// 卡牌对象  
    /// </summary>  
    public GameObject cardItem;  
    /// <summary>  
    /// 扇形半径  
    /// </summary>  
    public float size =30f;  
    /// <summary>  
    /// 卡牌出现最大位置  
    /// </summary>  
    private float minPos = 1.415f;  
    /// <summary>  
    /// 卡牌出现最小位置  
    /// </summary>  
    private float maxPos = 1.73f;  
    /// <summary>  
    /// 手牌列表  
    /// </summary>  
    private List<CardItem> cardList;  
    /// <summary>  
    /// 手牌位置  
    /// </summary>  
    private List<float> rotPos;  
    /// <summary>  
    /// 最大手牌数量  
    /// </summary>  
    private int CardMaxCount=8;  
  
    void Start()  
    {        InitCard();  
    }    /// <summary>  
    /// 数据初始化  
    /// </summary>  
    public  void InitCard()  
    {  
          rotPos=InitRotPos(CardMaxCount);  
    }    
    /// <summary>  
    /// 初始化位置  
    /// </summary>  
    /// <param name="count"></param>    
    /// <param name="interval"></param>    
    /// <returns></returns>    
    public List<float> InitRotPos(int count)  
    {        
        List<float> rotPos=new List<float>();  
        float interval = (maxPos - minPos)/count;  
        for (int i = 0; i < count; i++)  
        {            
            float nowPos = maxPos - interval * i;  
            rotPos.Add(nowPos);  
        }        
        return rotPos;  
    }  
    // Update is called once per frame  
    void Update()  
    {        
        TaskItemDetection();  
        RefereshCard();  
    }   
    /// <summary>  
    /// 添加卡牌  
    /// </summary>  
    public  void AddCard()  
    {        
        if (cardList==null)  
        {            
            cardList=new List<CardItem>();  
        }  
        if (cardList.Count>=CardMaxCount)  
        {            
            Debug.Log("手牌数量上限");  
            return;  
        }        
        GameObject item = Instantiate(cardItem,this.transform);  
        CardItem text=item.GetComponent<CardItem>();  
        text.RefreshData(rootPos,0,0,0);  
        cardList.Add(text);  
    }    
    /// <summary>  
    /// 手牌状态刷新  
    /// </summary>  
    public void RefereshCard()  
    {        
        if (cardList==null)  
        {            
           return;  
        }  
        for (int i = 0; i < cardList.Count; i++)  
        {
            cardList[i].RefreshData(rootPos,rotPos[i],size,i);   
        }  
    }    
    /// <summary>  
    /// 销毁卡牌  
    /// </summary>  
    public  void RemoveCard()  
    {        
        if (cardList==null)  
        {
            return;  
        }  
        CardItem item = cardList[cardList.Count - 1];  
        cardList.Remove(item);  
        Destroy(item.gameObject);  
    }    
	/// <summary>  
    /// 销毁卡牌  
    /// </summary>  
    /// <param name="item"></param>    
    public  void RemoveCard(CardItem item)  
    {        
        if (cardList==null)  
        {
	        return;  
        }
        cardList.Remove(item);  
        Destroy(item.gameObject);  
    }  
    private Vector3 oldmousePosition;  
          
    /// <summary>  
    /// 玩家操作检测  
    /// </summary>  
    public void TaskItemDetection()  
    {       
       if (Input.GetKeyDown(KeyCode.A))  
        {         
           AddCard();  
        }          
     }  
}
  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现杀戮尖塔的地图,可以借助Unity游戏引擎的强大功能和工具。 首先,我们需要创建一个具有正确视角的3D场景。在Unity中,可以使用内置的Terrain系统来快速生成地形,包括山脉、草地和水体等自然元素。然后,我们可以在地形上放置各种障碍物和景观特征,如树木、岩石和建筑物,以增加游戏的复杂度和可玩性。 接下来,我们需要设计和创建敌人和玩家角色的模型。使用Unity的内置的模型编辑器或外部建模软件,可以创建具有所需外观和动画的角色模型。然后,我们可以将这些模型导入Unity中,并将它们添加到场景中。 为了实现杀戮尖塔游戏玩法,需要编写相应的脚本来控制角色的行为。使用Unity的脚本编辑器,我们可以编写角色的移动、攻击和受伤等行为的代码逻辑。此外,还可以编写AI脚本来控制敌人的行为,使其具有智能化的攻击和防御策略。 此外,还可以通过使用Unity的粒子系统来创建特效,如爆炸、火焰和魔法效果,以增加游戏的视觉效果和丰富度。 最后,为了增加游戏的可玩性和挑战性,可以添加关卡设计和游戏流程。可以使用Unity的场景管理器和状态机来创建多个关卡,并设定不同的目标和难度。此外,还可以添加升级系统、奖励机制和排行榜等元素,以提高玩家的参与度和激励。 总之,借助Unity的强大功能和工具,可以有效实现杀戮尖塔的地图。通过合理设计和编写脚本,精心构建场景和角色模型,以及添加丰富的特效和关卡设计,可以为玩家带来更具挑战和乐趣的游戏体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值