学习游戏制作记录(实现震动效果,文本提示和构建游戏)9.13

发布于:2025-09-14 ⋅ 阅读:(21) ⋅ 点赞:(0)

1.实现屏幕的震动效果

为玩家添加Cinemachine Impulse Source 组件

EntityFX脚本:

    [Header("Screen Shader FX")]
    private CinemachineImpulseSource screenShake;//Start中自行获取对应组件
    [SerializeField] private float shakeMutiplier;//震动倍率
    public Vector3 shakeSwordImpact;//接剑时的震动方向
    public Vector3 shakeHighDamage;//受到高伤害的

    public void ScreenShake(Vector3 _shakePower)
    {
        screenShake.m_DefaultVelocity = new Vector3(_shakePower.x * player.facingDir, _shakePower.y) * shakeMutiplier;//设置震动方向

        screenShake.GenerateImpulse();//产生震动
    }

PlayerCatchSwordState脚本:
 

    public override void Enter()
    {
        base.Enter();

        sword = _Player.sword;

        _Player.entityFX.PlayDustFX();

        _Player.entityFX.ScreenShake(_Player.entityFX.shakeSwordImpact);//进入接剑状态的时候产生震动

PlayerStats脚本:

    protected override void DecreaseHealth(int _damage)
    {
        base.DecreaseHealth(_damage);

        if(isDead)
        {
            return;
        }

        if(_damage>GetMaxHealth()*.3f)
        {
            player.SetupKnockBackPower(new Vector2(10, 6));

            player.entityFX.ScreenShake(player.entityFX.shakeHighDamage);//受到超高伤害时产生震动

            int randomSound = Random.Range(34, 35);
            AudioManager.instance.PlaySFX(randomSound, null);
        }

        ItemData_Equipment itemData_Armor = Inventory.instance.GetEquipment(EquipmentType.Armor);

        if(itemData_Armor != null)
        {
            itemData_Armor.Effect(player.transform);
        }
    }

2.实现文本的弹出

创建一个文本

创建PopUpTextFx脚本并挂载:
 

    private TextMeshPro myText;//获取文本

    [SerializeField] private float speed;//上升速度
    [SerializeField] private float desappearSpeed;//消失速度
    [SerializeField] private float colorDesappearSpeed;//变透明的速度

    [SerializeField] private float lifeTime;//生命周期

    private float textTimer;//计时器

    void Start()
    {
        myText = GetComponent<TextMeshPro>();
        textTimer = lifeTime;
    }

    void Update()
    {
        transform.position = Vector2.MoveTowards(transform.position,new Vector2(transform.position.x, transform.position.y + 1), speed * Time.deltaTime);//文本的上升
        textTimer -= Time.deltaTime;

        if(textTimer < 0)
        {
            float alpha=myText.color.a-colorDesappearSpeed*Time.deltaTime;//实现文本的消失

            myText.color =new Color(myText.color.r,myText.color.g,myText.color.b,alpha);

            if (myText.color.a < 50)
                speed = desappearSpeed;//透明下降到一定程度开始消失

            if(myText.color.a<=0)
                Destroy(gameObject);
        }

    }

EntityFX脚本:


    [Header("Pop Up Text")]
    [SerializeField] private GameObject PopUpTextPrefab;//弹出文本预制体

    public void CreatePopUpText(string _text,Color _color)//传入文本和颜色
    {
        float randomX = Random.Range(-1, 1);
        float randomY = Random.Range(3, 5);

        Vector3 positionOffest=new Vector3(randomX, randomY, 0);//偏移量

        GameObject newText =Instantiate(PopUpTextPrefab,transform.position+positionOffest,Quaternion.identity);//生成

        newText.GetComponent<TextMeshPro>().text= _text;//设置文本和颜色
        newText.GetComponent <TextMeshPro>().color= _color;

    }

Skill脚本:
 

    public virtual bool CanbeUsed()
    {
        if (coolDownTime < 0)
        {
            UseSkill();
            coolDownTime = cooldown;
            return true;
        }

        else
        {
            player.entityFX.CreatePopUpText("技能在冷却", Color.white);//除黑洞外添加冷却的文本提示
            return false;
        }
    }

PlayerGroundedState脚本:


        if(Input.GetKeyDown(KeyCode.R)&&_Player.skill.blackhole.BlackholeUnlocked)
        {
           if( _Player.skill.blackhole.coolDownTime > 0)
            {
                _Player.entityFX.CreatePopUpText("技能在冷却", Color.white);
                return;//为黑洞添加提示
            }
            _PlayerStateMachine.ChangeState(_Player.blackholeState);
        }

CharactorState脚本:
 

    protected virtual void  DecreaseHealth(int _damage,Color _color)
    {
        if(isVolunerable)
        {
            _damage = Mathf.RoundToInt(_damage * 1.1f);
        }


        currentHealth -= _damage;

        if(_damage>0)
        {
            entityFX.CreatePopUpText(_damage.ToString(),_color);//提示伤害的数值,自行为燃烧伤害设置为红色字体
            
        }

        if(onHealthChange != null)
        {
            onHealthChange();
        }
    }

3.构建游戏

ItemData脚本:


#if UNITY_EDITOR
using UnityEditor;
#endif//确保只在Unity编辑器中使用

Inventory脚本:


    public List<ItemData> ItemDataBase;//数据库

    public void LoadDate(GameData gameData)
    {
        foreach (KeyValuePair<string, int> pair in gameData.Inventory)
        {
            foreach (var item in ItemDataBase)//读取数据库
            {
                if (item != null && item.ItemID == pair.Key)
                {
                    InventoryItem itemToLoad = new InventoryItem(item);

                    itemToLoad.stackSize = pair.Value;

                    LoadedItems.Add(itemToLoad);
                }
            }
        }

        foreach (string loadedItemID in gameData.equipmentId)
        {
            foreach (var item in ItemDataBase)
            {
                if (item != null && item.ItemID == loadedItemID)
                {
                    loadedEquipments.Add(item as ItemData_Equipment);
                }
            }
        }
    }

    #if UNITY_EDITOR

    [ContextMenu("Fill up Item data Base")]//只在Unity编辑器中使用下面的功能
    private void FillupItemDataBase()=> ItemDataBase=new List<ItemData>(GetItemDataBase());
    private List<ItemData> GetItemDataBase()
    {
        List<ItemData> itemDatas = new List<ItemData>();
        string[] assestsName = AssetDatabase.FindAssets("", new[] { "Assets/Data/Items" });

        foreach (string SQName in assestsName)
        {
            var SQpath = AssetDatabase.GUIDToAssetPath(SQName);
            var itemData = AssetDatabase.LoadAssetAtPath<ItemData>(SQpath);

            itemDatas.Add(itemData);
        }

        return itemDatas;
    }
#endif


网站公告

今日签到

点亮在社区的每一天
去签到