The question is answered, right answer was accepted
Issue with the script!

When we click on one of the cubes it will shoot projectiles. I have created a function to decide which capsule will shoot i.e TurnDecider() So at the beginning Player1 is active and so only it can shoot a projectile. As soon as he shoots the function TurnDecider() is called to change turn to Player2. So logically only Player2 should be shooting but in the game both Player2 and Player3 are shooting.
Left: Player 2
Center: Player 1
Right: Player 3
The scripts are given below.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManage : MonoBehaviour
{
private int playernumber;
private PlayerController a, b, c;
public bool fired = false;
public void InitialAssign()
{
playernumber = 1;
a = GameObject.Find("Player (1)").GetComponent<PlayerController>();
b = GameObject.Find("Player (2)").GetComponent<PlayerController>();
c = GameObject.Find("Player (3)").GetComponent<PlayerController>();
TurnDecider();
}
void Start()
{
InitialAssign();
}
public void PlayerSelector()
{
if (playernumber == 3)
{
playernumber = 1;
}
else
{
playernumber++;
}
TurnDecider();
}
public void TurnDecider()
{
switch (playernumber)
{
case 1:
a.isReady=true;
b.isReady = false;
c.isReady = false;
Debug.Log("Player 1 is ready!");
break;
case 2:
a.isReady = false;
b.isReady = true;
c.isReady = false;
Debug.Log("Player 2 is ready!");
break;
case 3:
a.isReady = false;
b.isReady = false;
c.isReady = true;
Debug.Log("Player 3 is ready!");
break;
}
}
// Update is called once per frame
void Update()
{
if (fired == true)
{
PlayerSelector();
Debug.Log(playernumber);
fired = false;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public GameObject projectile;
public float Power = 10f;
public float JumpPower;
private Rigidbody rb;
private Transform shooter;
public GameManage gamescript;
private string obj;
public bool isReady = false;
private bool isGround = false;
void Start()
{
rb = GetComponent<Rigidbody>();
shooter=transform.Find("Shooter");
}
void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Ground"))
{
isGround = true;
}
}
public void Fire()
{
GameObject ball = Instantiate(projectile, position: shooter.position, rotation: shooter.rotation);
ball.GetComponent<Rigidbody>().velocity = (GameObject.Find(obj).transform.position - shooter.position).normalized * Power;
}
public void Jump()
{
if (isGround)
{
rb.velocity = new Vector3(0f, JumpPower, 0f);
}
isGround = false;
}
void Update()
{
if (Input.GetMouseButtonDown(0) && isReady && isGround)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.tag == "Target")
{
Debug.Log("Fire Called by " + transform.name);
obj = hit.transform.name.ToString();
Fire();
gamescript.GetComponent<GameManage>().fired = true;
}
}
}
}
}
Is there a reason you aren't giving the command from your $$anonymous$$anager? Having the manager sort out who's active is fine, but having the individual objects checking if they're allowed to fire from their own Updates feels a bit clunky. You can just do that from the $$anonymous$$anager's Update.
This isn't a forum for code corrections, but I will help get you started. First, you can move most of that firing routine somewhere else.
// Place this into your PlayerController.
//
public bool AttemptFire() {
if (Input.Get$$anonymous$$ouseButtonDown(0) && isReady && isGround)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.tag == "Target")
{
Debug.Log("Fire Called by " + transform.name);
obj = hit.transform.name.ToString();
Fire();
// If we did fire
return true;
}
}
}
// If we didn't
return false;
}
Then have your manager keep track of which player is currently active
private PlayerController activePlayer;
Then use your big switch body there to set activePlayer to whichever PlayerController instance should fire next. You can figure out the rest.
Answer by degeta · Apr 06, 2018 at 03:54 PM
Can u check if the code is proper? And can this code be improved?
public class PlayerController : MonoBehaviour
{
public GameObject projectile;
public float Power = 10f;
public float JumpPower;
private Rigidbody rb;
private Transform shooter;
public GameManage gamescript;
private string obj;
public bool isReady = false;
private bool isGround = false;
void Start()
{
rb = GetComponent<Rigidbody>();
shooter=transform.Find("Shooter");
}
void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Ground"))
{
isGround = true;
}
}
public void Fire()
{
GameObject ball = Instantiate(projectile, position: shooter.position, rotation: shooter.rotation);
ball.GetComponent<Rigidbody>().velocity = (GameObject.Find(obj).transform.position - shooter.position).normalized * Power;
}
public void Jump()
{
if (isGround)
{
rb.velocity = new Vector3(0f, JumpPower, 0f);
}
isGround = false;
}
public bool AttemptFire()
{
if (Input.GetMouseButtonDown(0) && isReady && isGround)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.tag == "Target")
{
Debug.Log("Fire Called by " + transform.name);
obj = hit.transform.name.ToString();
Fire();
// If we did fire
return true;
}
}
}
// If we didn't
return false;
}
void Update()
{
}
}
public class GameManage : MonoBehaviour
{
private int playernumber;
private PlayerController a, b, c,active;
public void InitialAssign()
{
playernumber = 1;
a = GameObject.Find("Player (1)").GetComponent<PlayerController>();
b = GameObject.Find("Player (2)").GetComponent<PlayerController>();
c = GameObject.Find("Player (3)").GetComponent<PlayerController>();
TurnDecider();
}
void Start()
{
InitialAssign();
}
public void PlayerSelector()
{
if (playernumber == 3)
{
playernumber = 1;
}
else
{
playernumber++;
}
TurnDecider();
}
public void TurnDecider()
{
switch (playernumber)
{
case 1:
a.isReady=true;
b.isReady = false;
c.isReady = false;
active=a;
Debug.Log("Player 1 is ready!");
break;
case 2:
a.isReady = false;
b.isReady = true;
c.isReady = false;
active=b;
Debug.Log("Player 2 is ready!");
break;
case 3:
a.isReady = false;
b.isReady = false;
c.isReady = true;
active=c;
Debug.Log("Player 3 is ready!");
break;
}
}
void Update()
{
if (Input.GetMouseButtonDown(0)&&active.AttemptFire())
{
PlayerSelector();
}
}
}
If it's doing what it's supposed to do and you / your $$anonymous$$m think it's readable, then it works just fine.
I dont work with a $$anonymous$$m. I'm doing all this alone and I'm a beginner level unity developer. Just one year experience :) Anyways thanks for your support !
Follow this Question
Related Questions
Unity hub help 0 Answers
Ar foundation Face Tracking 0 Answers
how to download open jdk,sdk, ndk recommended for unity Unity 2019.3.1, without unity hub. 1 Answer
I cant get the basic FollowPlayer script to go to Main Camera in the hierarchy 0 Answers
I want to exactly put my player where i want it be. 0 Answers