3D等距旋转相机场景下2D角色精灵动画方向适配实现
3D等距视角玩家精灵动画方向适配问题
我正在尝试编写一套玩家精灵动画控制脚本,实现相机旋转时精灵动画方向自动调整的效果。当前项目为3D等距世界,每个朝向对应固定机位相机,场景中玩家为2D精灵,目前已独立编写玩家控制器、玩家动画、精灵渲染器三个脚本。
Player Controller(玩家控制器)
该控制器基于相机朝向实现移动逻辑,适配项目中多相机对应不同朝向的设计,代码如下:
public class PlayerController : MonoBehaviour { public float speed = 5f; void Update() { var moveInput = new Vector3(Input.GetAxis("Horizontal"), 0f , Input.GetAxis("Vertical")); moveInput = Camera.main.transform.TransformDirection(moveInput); moveInput.y = 0; moveInput = moveInput.normalized; transform.position += moveInput * Time.deltaTime * speed; } }
Player Animation(玩家动画)
我参考的这套玩家动画脚本原本是为2D控制器编写的,逻辑清晰但无法直接适配当前3D场景,我需要明确如何正确添加行走动画逻辑,让脚本可以追踪玩家当前朝向,同步更新精灵渲染器的显示内容。现有代码如下:
public class PlayerAnimation : MonoBehaviour { public Rigidbody2D body; public SpriteRenderer spriteRenderer; public List<Sprite> nSprite; public List<Sprite> neSprite; public List<Sprite> eSprite; public List<Sprite> seSprite; public List<Sprite> sSprite; public float frameRate; float idleTime; Vector3 direction; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { direction = new Vector3(Input.GetAxis("Horizontal"), 0f , Input.GetAxis("Vertical")).normalized; direction = Camera.main.transform.TransformDirection(direction); HandleSpriteFlip(); List<Sprite> directionSprites = GetSpriteDirection(); if(directionSprites != null) //holding direction { float playTime = Time.time - idleTime; //time since we sterted walking int totalFrames = (int)(playTime * frameRate); //total frames since we started int frame = totalFrames % directionSprites.Count; //current frame spriteRenderer.sprite = directionSprites[frame]; } else //holding nothing, input is neutral { idleTime = Time.time; } } void HandleSpriteFlip() { if (!spriteRenderer.flipX && direction.x < 0) { spriteRenderer.flipX = true; } else if (spriteRenderer.flipX && direction.x > 0) { spriteRenderer.flipX = false; } } List<Sprite> GetSpriteDirection() { List<Sprite> selectedSprites = null; if (direction.y > 0) //north { if (Mathf.Abs(direction.x) > 0) //east or west { selectedSprites = neSprite; } else {//neutral selectedSprites = nSprite; } } else if (direction.y < 0) //south { if (Mathf.Abs(direction.x) > 0) //east or west { selectedSprites = seSprite; } else {//neutral selectedSprites = sSprite; } } else //neutral { if (Mathf.Abs(direction.x) > 0) //east or west { selectedSprites = eSprite; } } return selectedSprites; } }
Sprite Renderer(精灵渲染器)
该精灵渲染器脚本来自过往相关问题,可在静止物体上实现相机角度更新时的精灵切换效果,但我不清楚如何修改该脚本,使其可适配会移动、朝向动态变化的玩家对象。现有代码如下:
private SpriteRenderer spriteRenderer; public Transform plane; public Camera cam; private const float step = 22.5f; public Sprite N, NW, W, SW, S, SE, E, NE; public void Start() => spriteRenderer = GetComponent<SpriteRenderer>(); public void Update() { var projected = Vector3.ProjectOnPlane(cam.transform.forward, plane.up); var angle = Vector3.SignedAngle(projected, plane.forward, plane.up); var AbsAngle = Mathf.Abs(angle); if (AbsAngle < step) spriteRenderer.sprite = N; else if (AbsAngle < step*3) spriteRenderer.sprite = Mathf.Sign(angle) < 0 ? NW : NE; else if (AbsAngle < step*5) spriteRenderer.sprite = Mathf.Sign(angle) < 0 ? W : E; else if (AbsAngle < step*7) spriteRenderer.sprite = Mathf.Sign(angle) < 0 ? SW : SE; else spriteRenderer.sprite = S; Billboard(spriteRenderer.transform, cam); } public void Billboard(Transform character, Camera mainCamera) { var dir = plane.position - mainCamera.transform.position; var LookAtRotation = Quaternion.LookRotation(dir); var LookAtRotationOnly_Y = Quaternion.Euler(character.rotation.eulerAngles.x, LookAtRotation.eulerAngles.y,character.eulerAngles.z); character.rotation = LookAtRotationOnly_Y; }
内容的提问来源于stack exchange,提问作者naturalcrybaby
相关产品推荐
相关产品推荐

