Wdream

Personal Website

The Sky's The Limit.


Unity 2D 问题总结

目录

Unity 2D 问题总结

人物穿过地面下坠

人物需要包含组件

  1. RigidBody 2D
  2. Box Collider 2D (最好使用Capsule Collider 2D)

image-20250227101027270

地面需要包含组件

  1. Tilemap Collider 2D

image-20250227101158194

人物水平移动卡住

因为使用了矩形的碰撞箱,对Tilemap的碰撞产生了问题,替换为胶囊形的即可。

人物需要包含组件

  1. RigidBody 2D
  2. 使用Capsule Collider 2D

人物倒地

RigidBody 2D > Freeze Z锁定Z轴

动画不会立即过渡

将过渡箭头的退出时间取消

image-20250301233059787

人物爬墙动画相反

在墙上滑行的时候,逻辑朝向是面向墙的,动画朝向是背向墙面的

如果出现人物面向墙面,说明上墙的时候人物的朝向为背向墙面的,只要此时不让人物上墙即可

if(player.GetWallDirection() * xInput > 0 && player.IsWallDetected() && !player.IsGroundedDetected(2.0f))
{
    stateMachine.ChangeState(player.wallSlideState);
}

人物靠墙时,刚跳起就上墙

将此时的地面监测距离调高,可以重载原先的侦测函数,增加一个偏移量参数

public bool IsGroundedDetected(float offset)
{
    //以groundCheck为中心,向下画一条长度为groundCheckRadius的线,如果碰到了地面,那么返回true
    return Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckRadius+offset, whatIsGround);
}
if(player.GetWallDirection() * xInput > 0 && player.IsWallDetected() && !player.IsGroundedDetected(2.0f))
{
    stateMachine.ChangeState(player.wallSlideState);
}

人物跳墙时会出现速度异常

因为人物跳墙时需要同时获得水平和纵向的速度,而这两个速度原先在Enter中一次性赋予了角色,在某些时候会出现问题——人物只获得了水平速度

解决办法是在Update中持续更新角色的速度

人物和怪物发生碰撞

人物可以踩在怪物头上以及可以推着怪物走。

Edit > Project Settings > Physics2D > 取消 Player 和 Enemy的碰撞

注意将Player和Enemy的层级设置为对应的层级

image-20250318212103453

image-20250318212125683

image-20250318211915537

人物闪烁效果

新建 > Material

image-20250318215205487

新建EntityFX 脚本

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

namespace Script.Entity
{
    public class EntityFX : MonoBehaviour
    {
        private SpriteRenderer sr;
        [Header("Flash FX")] 
        [SerializeField]private Material hitMat;
        private Material originalMat;

        private void Start()
        {
            sr = GetComponentInChildren<SpriteRenderer>();
            originalMat = sr.material;
        }

        private IEnumerator FlashFX()
        {
            sr.material = hitMat;
            yield return new WaitForSeconds(0.3f);
            sr.material = originalMat;
        }
    }
}

添加到Player/ Enemy身上

image-20250319104632401

修改Entity方法Damage

using Unity.Mathematics;
using UnityEngine;

namespace Script.Entity
{
    public class Entity : MonoBehaviour
    {
        #region Components
        public EntityFX Fx { get;private set; }
        
        #endregion
        
        //...
        
        protected virtual void  Awake()
        {
            //获取组件
            Fx = GetComponent<EntityFX>();
        }
     
 
        public void Damage()
        {
            //携程实现跨脚本调用方法
            Fx.StartCoroutine("FlashFX");
            Debug.Log(" i was Damaged");
        }
    }
}

预制体prefabs设置

创建

create -> scene -> prefab

image-20250326145909032

注意修改时需要勾选,否则assets中的prefabs也会被取消,修改完之后可以取消勾选,防止出现在场景中影响视野。

image-20250328210945392

引用参数异常

private void CheckToCloneAttack()
{
    if (!canAttack) return;
    var randomIndex = Random.Range(0, targetsList.Count);
    var offsetX = Random.Range(0, 100) > 50f ? 0.9f : -1.1f;
    var dir = offsetX > 0 ? -1 : 1;
    //targets[randomIndex]是引用,不能直接传递,或者说传递了最好不要直接使用
   SkillManager.Instance.Clone.CreatePrefabs(targetsList[randomIndex],dir,offsetX,0);
    SetCloneAttackTimer(cloneAttackCoolDown);
    attackAmount--;
}

如果非要传递,不要直接使用

public void CreatePrefabs(Transform newTf, int dir, float offsetX, float offsetY)
{
    base.CreatePrefabs(prefab);
    if (!prefabsController) return;
    var clonePos = new Vector2(newTf.position.x + offsetX, newTf.position.y + offsetY);
    ((ClonePrefabsController)prefabsController).SetUpPrefabs(clonePos, duration, dir);
}

Comments