- Home /
Player doesn't move after changing his position
Hi guys
I'm currently working on a tactical RPG and I have the following issue:
When the player's health is <=0 , I set him to a specific position in the grid of the game. However, after that, when I click on the player to move him to a specific tile, he doesn't move.
I'm using this script to change the player's positon. It's attached to each player in the game:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Jogador : MonoBehaviour
{
[SerializeField] private Mapa mapa;
public Vector2Int GridPosition;
public bool isPlayer = false;
public float Health = 50f;
public GameObject Spawnador;
private void Awake()
{
if (!mapa) mapa = FindObjectOfType<Mapa>();
}
// Start is called before the first frame update
void Start()
{
foreach(var tile in mapa.GridMatriz)
{
//tile.jogador = this;
}
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit) && hit.transform == this.transform)
{
mapa.GetComponent<Movimentação>().TurnEnd();
isPlayer = true;
mapa.GetComponent<Movimentação>().TurnStart();
Debug.Log("clicou");
}
}
CheckHealth();
}
public void CheckHealth()
{
if (Health <= 0)
{
this.transform.position = new Vector3(Spawnador.transform.position.x, Spawnador.transform.position.y, Spawnador.transform.position.z);
}
}
}
I'm using this script for the movement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Movimentação : 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, SpawBala.transform.rotation);
Rigidbody BalaRigid = tiro.GetComponent<Rigidbody>();
if (SpawBala.tag == "Bala1")
{
BalaRigid.AddForce(Vector3.forward * ProjetilVeloc);
}
if (SpawBala.tag == "Bala2")
{
BalaRigid.AddForce(Vector3.back * 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;
}
}
}
I really don't know what's going on
Answer by BoraHorzaGobuchul · Nov 04, 2019 at 05:37 AM
@rodrigodebem7 I can only give some general advice. With a specific intractable problem that can't be solved, it's best to step back and look at the bigger picture and apply general programming techniques e.g.: 1) Can you be sure that all the required code is being called by Unity with all the expected values ? Debug.Log everything at the entry point for each of the methods called by Unity - before any custom code. 2) Methods should be no more than 10 lines long. The Update method is doing a lot of specific tasks. These tasks need to be clearly defined and moved into their own private methods or classes. One technique is wherever you have a comment, that comment is a potential name for the method e.g. //checks if the tile is available based on the line and column of the unit => bool IsTileAvailableForLineAndColumnOfTheUnit() 3) Separate your custom logic from Unity and place into their own methods (or better, separate classes). Because the custom logic is now outside of Unity, it is easier to validate and test without actually running the game.
Have a look at this: https://www.slideshare.net/dhelper/writing-clean-code-in-c-and-net
Your answer
Follow this Question
Related Questions
Error CS0029 1 Answer
Convert vector2int to vector3 1 Answer
2D Character Animation - even starting if I'm not pressing A or D 2 Answers