Unity 2D游戏子弹左右射击及敌标签触发射击问题咨询
Hey there! Let's tackle those two issues with your shooting mechanics. I'll walk you through each fix with clear code changes and explanations so you can get your game working as intended.
1. Make Bullets Shoot in the Character's Facing Direction
Right now, bullets always fire left because you're using barrel.up (which is likely fixed to point left by default) and your character doesn't update its facing direction when moving. Here's how to fix that:
First, add logic to flip your character's sprite when they move left or right. Insert this into your Update method:
// Update character's facing direction based on movement if (dirX != 0) { // Set scale.x to 1 for right, -1 for left localScale.x = dirX > 0 ? 1 : -1; transform.localScale = localScale; }
Next, modify your Fire method to apply force in the direction the character is facing. Instead of barrel.up, use barrel.right multiplied by the character's facing scale (since localScale.x tells us which way they're looking):
void Fire() { float bulletDirection = transform.localScale.x; var firedBullet = Instantiate(bullet, barrel.position, barrel.rotation); // Apply force along the right axis, adjusted for facing direction firedBullet.AddForce(barrel.right * bulletDirection * bulletSpeed); }
Now when your character faces right (scale.x = 1), bullets shoot right; when facing left (scale.x = -1), bullets shoot left.
2. Only Shoot When an Enemy is Detected
To restrict firing to only when an enemy is in range, we'll add a raycast check before spawning the bullet. This raycast will detect if any object with the enemy tag is in front of the character.
First, add a serialized field to adjust detection range (you can tweak this in the Unity Inspector later):
[SerializeField] float enemyDetectionRange = 3f;
Then update your Update method to only call Fire if an enemy is detected, and add a new method to handle the detection:
void Update() { dirX = CrossPlatformInputManager.GetAxis("Horizontal"); // Update facing direction (from step 1) if (dirX != 0) { localScale.x = dirX > 0 ? 1 : -1; transform.localScale = localScale; } if (CrossPlatformInputManager.GetButtonDown("Jump")) Jump(); // Only fire if Fire1 is pressed AND an enemy is in range if (CrossPlatformInputManager.GetButtonDown("Fire1") && IsEnemyInRange()) { Fire(); } } // Checks if an enemy is within detection range bool IsEnemyInRange() { float direction = transform.localScale.x; // Cast a 2D ray from the barrel, in the character's facing direction RaycastHit2D hit = Physics2D.Raycast(barrel.position, Vector2.right * direction, enemyDetectionRange); // Return true if we hit an object with the 'enemy' tag return hit.collider != null && hit.collider.CompareTag("enemy"); }
Quick Notes for Enemy Detection:
- Make sure your enemy objects have the
enemytag assigned (create it in the Inspector's tag dropdown if it doesn't exist). - Adjust
enemyDetectionRangein the Inspector to set how far the character can detect enemies. - If you want a wider detection area (like a circle instead of a narrow ray), replace
Physics2D.RaycastwithPhysics2D.OverlapCircle.
Full Modified Character Script
Here's the complete script with all fixes applied:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityStandardAssets.CrossPlatformInput; public class Character : MonoBehaviour { Rigidbody2D rb; float dirX; [SerializeField] float moveSpeed = 5f, jumpForce = 400f, bulletSpeed = 500f; [SerializeField] float enemyDetectionRange = 3f; // New detection range field Vector3 localScale; public Transform barrel; public Rigidbody2D bullet; void Start() { localScale = transform.localScale; rb = GetComponent<Rigidbody2D>(); } void Update() { dirX = CrossPlatformInputManager.GetAxis("Horizontal"); // Update character facing direction if (dirX != 0) { localScale.x = dirX > 0 ? 1 : -1; transform.localScale = localScale; } if (CrossPlatformInputManager.GetButtonDown("Jump")) Jump(); // Only fire if enemy is detected if (CrossPlatformInputManager.GetButtonDown("Fire1") && IsEnemyInRange()) { Fire(); } } void FixedUpdate() { rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y); } void Jump() { if (rb.velocity.y == 0) rb.AddForce(Vector2.up * jumpForce); } bool IsEnemyInRange() { float direction = transform.localScale.x; RaycastHit2D hit = Physics2D.Raycast(barrel.position, Vector2.right * direction, enemyDetectionRange); return hit.collider != null && hit.collider.CompareTag("enemy"); } void Fire() { float bulletDirection = transform.localScale.x; var firedBullet = Instantiate(bullet, barrel.position, barrel.rotation); firedBullet.AddForce(barrel.right * bulletDirection * bulletSpeed); } }
Tweak the values like enemyDetectionRange or bulletSpeed in the Inspector to fit your game's feel. Let me know if you run into any snags!
内容的提问来源于stack exchange,提问作者ras2

