Unity2D仿元气骑士角色向左射击异常问题求助
问题描述
开发类《元气骑士》游戏,采用单摇杆控制角色与武器,参考原作操作逻辑。角色朝右时射击正常,朝左时出现以下异常:
- shotPoint(子弹发射点)未随武器同步翻转,武器在左侧时视觉呈倒置状态;
- 子弹仅在场景生成但无法正常飞行,疑似刚生成就触发碰撞;
- 子弹发射后始终朝右飞行,未朝向武器指向方向。
相关代码
Player.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { public Joystick joystick; public float speed; private Rigidbody2D rb; private Vector2 moveInput; private Vector2 moveVelocity; private Animator anim; private bool facingRight = true; void Start() { rb = GetComponent < Rigidbody2D>(); anim = GetComponent<Animator>(); } void Update() { moveInput = new Vector2(joystick.Horizontal, joystick.Vertical); moveVelocity = moveInput.normalized * speed; if (moveInput.x == 0) { anim.SetBool("isRunning", false); } else { anim.SetBool("isRunning", true); } if(!facingRight && moveInput.x > 0) { Flip(); } else if(facingRight && moveInput.x < 0) { Flip(); } } void FixedUpdate() { rb.MovePosition(rb.position + moveVelocity * Time.fixedDeltaTime); } public void Flip() { facingRight = !facingRight; transform.Rotate(0f, 180f, 0f); } }
Gun.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Gun : MonoBehaviour { public Joystick joystick; public float offset; public float rotZ; private SpriteRenderer spriteRender; public GameObject bullet; public Transform shotPoint; private float timeBtwShots; public float startTimeBtwShots; private Player player; void Start() { spriteRender = GetComponent<SpriteRenderer>(); player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>(); } void Update() { if (Mathf.Abs(joystick.Horizontal) > 0.001f || Mathf.Abs(joystick.Vertical) > 0.001f) { rotZ = Mathf.Atan2(joystick.Vertical, joystick.Horizontal) * Mathf.Rad2Deg; } transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset); if (rotZ < 90 && rotZ > -90) { spriteRender.flipY = false; } else { spriteRender.flipY = true; } timeBtwShots -= Time.deltaTime; } public void ShootButton() { Instantiate(bullet, shotPoint.position, transform.rotation); timeBtwShots = startTimeBtwShots; } }
Bullet.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Bullet : MonoBehaviour { public float speed; public float lifetime; public float distance; public int damage; public LayerMask whatIsSolid; void Start() { } void Update() { RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, transform.right, distance, whatIsSolid); if (hitInfo.collider != null) { if (hitInfo.collider.CompareTag("Enemy")) { hitInfo.collider.GetComponent<Enemy>().TakeDamage(damage); } Destroy(gameObject); } transform.Translate(Vector2.right * speed * Time.deltaTime); } }
问题排查与修复方案
问题1:shotPoint未同步翻转、武器视觉倒置
核心原因:角色翻转使用transform.Rotate(0f,180f,0f)会让武器子物体绕Y轴旋转,与Gun脚本中单独计算的Z轴旋转叠加,导致姿态混乱;同时武器精灵翻转逻辑未考虑角色朝向的影响。
修复代码:
- 修改Player的Flip方法,改用X轴缩放实现2D角色翻转(避免子物体旋转冲突):
public void Flip() { facingRight = !facingRight; Vector3 scale = transform.localScale; scale.x *= -1; transform.localScale = scale; }
- 调整Gun脚本的输入方向与翻转逻辑,结合角色朝向修正武器旋转:
void Update() { // 根据角色朝向修正摇杆输入,确保武器方向与视觉一致 float horizontalInput = joystick.Horizontal * (player.facingRight ? 1 : -1); float verticalInput = joystick.Vertical; if (Mathf.Abs(horizontalInput) > 0.001f || Mathf.Abs(verticalInput) > 0.001f) { rotZ = Mathf.Atan2(verticalInput, horizontalInput) * Mathf.Rad2Deg; } transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset); // 简化精灵翻转判断 spriteRender.flipY = rotZ < -90 || rotZ > 90; timeBtwShots -= Time.deltaTime; }
问题2:子弹刚生成就碰撞消失
核心原因:shotPoint位置与玩家碰撞体重叠,或Raycast检测范围过大,触发了玩家自身碰撞。
修复方案:
- 调整shotPoint在武器子物体中的位置,确保其完全处于玩家碰撞体外;
- 在Bullet脚本中跳过玩家自身碰撞检测:
void Update() { RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, transform.right, distance, whatIsSolid); if (hitInfo.collider != null) { // 跳过玩家自身,避免刚生成就销毁 if (hitInfo.collider.CompareTag("Player")) return; if (hitInfo.collider.CompareTag("Enemy")) { hitInfo.collider.GetComponent<Enemy>().TakeDamage(damage); } Destroy(gameObject); } transform.Translate(transform.right * speed * Time.deltaTime); }
问题3:子弹始终朝右飞行
核心原因:Bullet脚本使用世界空间的Vector2.right作为移动方向,未跟随子弹自身的旋转朝向。
修复代码:
将Bullet的移动逻辑改为使用自身局部空间的右方向,确保与武器指向一致:
// 替换原Translate代码 transform.Translate(transform.right * speed * Time.deltaTime);
若追求更稳定的物理效果,可给子弹添加Rigidbody2D组件,在Gun脚本中直接设置速度:
public void ShootButton() { GameObject bulletObj = Instantiate(bullet, shotPoint.position, transform.rotation); Rigidbody2D rb = bulletObj.GetComponent<Rigidbody2D>(); if(rb != null) { rb.velocity = transform.right * speed; } timeBtwShots = startTimeBtwShots; }
同时移除Bullet脚本Update中的Translate代码,由刚体控制移动。
内容的提问来源于stack exchange,提问作者Nethereal
相关产品推荐
相关产品推荐

