user11660804
user11660804

Reputation:

Unity Player is shooting at himself

I have the following issue in my game:

There're two characters in the scene and they can shoot at each other. There is an empty game object attached in the front of each other called "SpawnBullet", which spawns the projectile, as you can see in the image.

enter image description here

The problem is that the game object called "Player 2" is shooting at himself, the bullet is going in his direction. Even when I rotate the SpawnBullet. In Player 1 it works fine.

This script is attached to the players

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Moviment : MonoBehaviour
{
    //player variables
    public GameObject player;
    public GameObject[] Personagens;

    //moving variables
    Vector3 targetPosition;
    float posY = 1;
    public float velocity = 0.2f;
    public float movMax = 3;
    public bool ismoving = false;
    public bool moveEnabled;
    public int aux;

    //bullet variables
    public GameObject projetil;
    private GameObject SpawBala;
    public float ProjetilVeloc = 500f;

    private void Start()
    {
        //sets the first unit as the active unit at the start of the game
        Personagens[0].GetComponent<Jogador>().isPlayer = true;
        TurnStart();

    }

    // Update is called once per frame
    void Update()
    {
        //left mouse button to start movement
        if (Input.GetMouseButtonDown(0))
        {
            //raycast checks and returns an object, if it's a tile, the unit moves
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            ismoving = true;

            if (Physics.Raycast(ray, out hit))
            {
                if (hit.transform.tag == "Tile")
                {
                    //checks if the tile is available based on the max movement of the unit
                    Tile tileAux = hit.transform.gameObject.GetComponent<Tile>();
                    Jogador scriptJog = player.GetComponent<Jogador>();
                    if ((tileAux.TilePostion.x - scriptJog.GridPosition.x) + (tileAux.TilePostion.y - scriptJog.GridPosition.y) >= -movMax && (tileAux.TilePostion.x - scriptJog.GridPosition.x) + (tileAux.TilePostion.y - scriptJog.GridPosition.y) <= movMax)
                    {
                        if ((tileAux.TilePostion.x - scriptJog.GridPosition.x) - (tileAux.TilePostion.y - scriptJog.GridPosition.y) >= -movMax && (tileAux.TilePostion.x - scriptJog.GridPosition.x) - (tileAux.TilePostion.y - scriptJog.GridPosition.y) <= movMax)
                        {
                            targetPosition = (hit.transform.position);
                            targetPosition.y = posY;
                            moveEnabled = true;
                        }

                    }
                }
            }

        }

        //right click to shoot
        if (Input.GetMouseButtonDown(1))
        {
            //raycast checks and returns an object, if it's a tile, the unit shoots
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                //checks if the tile is available based on the line and column of the unit
                Tile tileAux = hit.transform.gameObject.GetComponent<Tile>();
                Jogador scriptJog = player.GetComponent<Jogador>();

                if (tileAux.TilePostion.x == scriptJog.GridPosition.x || tileAux.TilePostion.y == scriptJog.GridPosition.y)
                {
                    if (tileAux.TilePostion.x > scriptJog.GridPosition.x)
                        tileAux.TilePostion.x = 5;
                    else
                        tileAux.TilePostion.x = 0;

                    if (tileAux.TilePostion.y > scriptJog.GridPosition.y)
                        tileAux.TilePostion.y = 5;
                    else
                        tileAux.TilePostion.y = 0;

                    Debug.Log(tileAux.TilePostion.x);
                    Debug.Log(tileAux.TilePostion.y);

                    //instantiates the bullet
                    GameObject tiro = Instantiate(projetil, SpawBala.transform.position, Quaternion.identity, player.transform);
                    Rigidbody BalaRigid = tiro.GetComponent<Rigidbody>();
                    BalaRigid.AddForce(Vector3.forward * ProjetilVeloc);
                }
            }
        }

        //player moves until reaches the position
        if (player.transform.position != targetPosition)
        {
            player.transform.position = Vector3.MoveTowards(player.transform.position, targetPosition, velocity);
            if (player.transform.position == targetPosition)
                ismoving = false;
        }

        //if player reaches position, it's deselected
        if (moveEnabled && !ismoving)
        {
            player.GetComponent<Jogador>().isPlayer = false;
            moveEnabled = false;
        }
    }

    public void TurnStart()
    {
        //makes the selected unit the active unit
        for (int i = 0; i < Personagens.Length; i++)
        {
            if (Personagens[i].GetComponent<Jogador>().isPlayer == true)
            {
                player = Personagens[i];
                posY = player.transform.position.y;
                targetPosition = player.transform.position;
                SpawBala = player.transform.GetChild(0).gameObject;
            }
        }
    }

    public void TurnEnd()
    {
        //desactivates all units
        for(int i = 0; i < Personagens.Length; i++)
        {
            Personagens[i].GetComponent<Jogador>().isPlayer = false;
        }
    }
}

And I'm using this section (copied from above) to shoot:

//right click to shoot
        if (Input.GetMouseButtonDown(1))
        {
            //raycast checks and returns an object, if it's a tile, the unit shoots
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                //checks if the tile is available based on the line and column of the unit
                Tile tileAux = hit.transform.gameObject.GetComponent<Tile>();
                Jogador scriptJog = player.GetComponent<Jogador>();

                if (tileAux.TilePostion.x == scriptJog.GridPosition.x || tileAux.TilePostion.y == scriptJog.GridPosition.y)
                {
                    if (tileAux.TilePostion.x > scriptJog.GridPosition.x)
                        tileAux.TilePostion.x = 5;
                    else
                        tileAux.TilePostion.x = 0;

                    if (tileAux.TilePostion.y > scriptJog.GridPosition.y)
                        tileAux.TilePostion.y = 5;
                    else
                        tileAux.TilePostion.y = 0;

                    Debug.Log(tileAux.TilePostion.x);
                    Debug.Log(tileAux.TilePostion.y);

                    //instantiates the bullet
                    GameObject tiro = Instantiate(projetil, SpawBala.transform.position, Quaternion.identity, player.transform);
                    Rigidbody BalaRigid = tiro.GetComponent<Rigidbody>();
                    BalaRigid.AddForce(Vector3.forward * ProjetilVeloc);
                }
            }
        }

Upvotes: 2

Views: 626

Answers (1)

DoubleD
DoubleD

Reputation: 21

When you add the force to the bullet you are using Vector3.forward. You need to use transform.forward instead.

Vector3.forward is always a constant (0, 0, 1). Think of the it as the forward direction of your world. It never changes.

transform.forward however will give the forward facing direction of the gameObject (the player). When you rotate your player it's transform.forward will change accordingly.

The reason Player 1 appears to be working correctly is because it is facing the same direction as Vector3.forward.

Upvotes: 1

Related Questions