You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中子弹无法在Player位置生成,始终从中心生成求助

问题描述

我是Unity和StackOverflow的新手,目前遇到一个问题:生成子弹(Projectile)时,本该在Player的当前位置实例化,但实际子弹始终从中心位置生成,而非Player位置。以下是相关脚本代码,恳请各位提供解决建议。

SpawnobjectController 脚本

public class SpawnobjectController : MonoBehaviour
{
    [SerializeField]
     GameObject projectilereference;
    
    [SerializeField]
     GameObject enemyreference;

    [SerializeField]
     GameObject playerreference;

    void Start()
    {
        StartCoroutine(Enemycoroutine());
        StartCoroutine(ProjectileCoroutine());
 }

     
    void SpawnProjectile() 
    {
        
        Instantiate(projectilereference, new Vector3(playerreference.transform.position.x,projectilereference.transform.position.y,0.0f), Quaternion.identity);
    }

    IEnumerator ProjectileCoroutine() 
    {
        while (true)
        {
            SpawnProjectile();
            yield return new WaitForSeconds(2.0f);
        }
    }



    IEnumerator Enemycoroutine()
    {
        while (true) { 
        SpawnEnemy();
        yield return new WaitForSeconds(1.0f);
    }
    }
    void SpawnEnemy() 
    {
        Instantiate(enemyreference, enemyreference.transform.position, Quaternion.identity);
    }
}

PlayerController 脚本

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

public class PlayerController : MonoBehaviour
{
    float _horizontalAxisPlayer;
    float _playerSpeed = 5f;
    float _maxXBoundry = 2.31f;
    void Start()
    {
        
    }

    
    void Update()
    {
        ControlPlayerBoundries();
        PlayerMovement();
    }

    void PlayerMovement() 
    {
        _horizontalAxisPlayer = Input.GetAxis("Horizontal")*_playerSpeed*Time.deltaTime;
        transform.Translate(new Vector3(_horizontalAxisPlayer, 0.0f, 0.0f));
    }

    void ControlPlayerBoundries() 
    {
        if (transform.position.x>_maxXBoundry)
        {
            transform.position = new Vector3(_maxXBoundry,transform.position.y,0.0f);
        }
        else if (transform.position.x<-_maxXBoundry)
        {
            transform.position = new Vector3(-_maxXBoundry, transform.position.y, 0.0f);
        }

    }
}

EnemyController 脚本

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

public class EnemyController : MonoBehaviour
{
    [SerializeField]
    private float enemeySpeed = 2f;
    void Start()
    {
        
    }

    
    void Update()
    {
        transform.Translate(Vector3.down * enemeySpeed * Time.deltaTime);
    }
}

ProjectileController 脚本

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

public class ProjectileController : MonoBehaviour
{
    [SerializeField]
   private GameObject Playerref;
    [SerializeField]
    private float projectile_speed = 2f;
    void Start()
    {
        
    }

    
    void Update()
    {
      //  print(Playerref.transform.position);
        
       
    }

    private void LateUpdate()
    {
        transform.Translate(new Vector3(transform.position.x, 0.5f) * projectile_speed * Time.deltaTime);
    }
}

解决建议

1. 修复子弹生成位置问题

核心问题在SpawnobjectController的SpawnProjectile方法里——你用了预制体自身的Y轴位置(projectilereference.transform.position.y),而不是Player的Y轴位置。预制体默认放在场景中心,所以子弹总是从中心生成。

修改后的代码:

void SpawnProjectile() 
{
    // 直接使用Player的完整位置生成子弹
    Instantiate(projectilereference, playerreference.transform.position, Quaternion.identity);
    
    // 如果需要让子弹从Player上方一点的位置发射(比如头顶),可以加偏移:
    // Vector3 spawnPos = playerreference.transform.position + new Vector3(0, 0.5f, 0);
    // Instantiate(projectilereference, spawnPos, Quaternion.identity);
}

2. 优化敌人生成逻辑(可选)

当前SpawnEnemy方法也是用预制体的位置生成敌人,会导致所有敌人从同一个位置出现。可以改成随机在屏幕上方生成:

// 先在SpawnobjectController里添加敌人生成范围变量
[SerializeField] private float _enemySpawnY = 6f;

void SpawnEnemy() 
{
    // 随机X轴位置,和Player的移动边界保持一致
    float randomX = Random.Range(-_maxXBoundry, _maxXBoundry);
    Vector3 spawnPos = new Vector3(randomX, _enemySpawnY, 0);
    Instantiate(enemyreference, spawnPos, Quaternion.identity);
}

3. 修复子弹移动逻辑

ProjectileController的LateUpdate里,移动代码写错了——用transform.position.x作为X轴移动量会让子弹越跑越偏,应该用固定方向(比如向上):

private void LateUpdate()
{
    // 让子弹沿Y轴正方向移动
    transform.Translate(Vector3.up * projectile_speed * Time.deltaTime);
}

内容的提问来源于stack exchange,提问作者Niks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:40:28