Updating with full code:
Unfortunately I thought making a variable private in the parent class would hide it from children classes… this doesn’t seem to be the case?
This is my player controller, and from it we detect when the player has touched their mobile screen; it fires a ray into the world and checks to see if the gameobject (tile) it’s hit can be moved to:
public class PlayerMotion : GameplayController
{
public static Animator anim;
Ray ray;
RaycastHit hit;
Camera MainCamera;
Transform hitTransform;
Vector3 startPos, endPos;
float inputTime01, inputTime02, warpSpeed, warpSpeedNormalizer;
protected override void Start()
{
base.Start();
anim = GetComponentInChildren<Animator>();
MainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
}
protected override void Update ()
{
if (GameManager.enemiesTurn)
return;
if (Input.GetMouseButtonDown(0))
{
startPos = Input.mousePosition;
inputTime01 = Time.time;
}
if (Input.GetMouseButtonUp(0))
{
inputTime02 = Time.time;
endPos = Input.mousePosition;
if (Vector3.Distance(startPos, endPos) < 140.0f) // click
{
Raycast(endPos);
}
else // swipe
{
if (hitTransform != null)
{
if (inputTime02 - inputTime01 < 0.2f)
{
Move();
}
}
}
}
}
void Raycast(Vector3 hitPos) // we've clicked a point on the screen
{
ray = MainCamera.ScreenPointToRay(hitPos);
if (Physics.Raycast(ray, out hit, 50.0f, tile_LayerMask)) // selected a tile - is it unlocked?
{
if (TileValidity(hit.transform)) // THIS IS ALWAYS FALSE
{
hitTransform = hit.transform;
tileMaster.EnableSelectionTile(hitTransform.position, hitTransform.name);
}
else
{
tileMaster.DisableSelectionTile();
hitTransform = null;
}
if (hitTransform != null)
transform.LookAt(hitTransform.position);
}
}
void Move() // PROBLEM IS ABOVE
{
myTile.UnlockTile();
tileMaster.HideAllTiles();
StartCoroutine(Warp());
}
IEnumerator Warp()
{
anim.SetBool("Warp", true);
warpSpeed = 0.2f;
warpSpeedNormalizer = 1.0f / warpSpeed;
warpSpeed = 0.0f;
startPos = transform.position;
endPos = hitTransform.position;
while (warpSpeed < 0.5f)
{
transform.position = Vector3.Lerp(startPos, endPos, warpSpeed);
warpSpeed += Time.deltaTime * warpSpeedNormalizer;
yield return null;
}
anim.SetBool("Warp", false);
while (warpSpeed < 1.0f)
{
transform.position = Vector3.Lerp(startPos, hitTransform.position, warpSpeed);
warpSpeed += Time.deltaTime * warpSpeedNormalizer;
yield return null;
}
transform.position = endPos;
hitTransform = null;
EventManager.AdjustAP(-1);
tileMaster.UnhideAllTiles();
ForcedLockTile();
}
GameplayController…
public class GameplayController : MonoBehaviour
{
protected int tile_LayerMask;
protected TileController myTile;
protected TileMaster tileMaster;
void Awake ()
{
tileMaster = GameObject.FindGameObjectWithTag("GameManager").GetComponent<TileMaster>();
tile_LayerMask = LayerMask.GetMask("Tile");
}
protected virtual void Start()
{
ForcedLockTile();
}
protected virtual void ForcedLockTile()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, Vector3.down, out hit, 5.0f, tile_LayerMask))
{
if (hit.transform == null)
return;
myTile = hit.transform.GetComponent<TileController>();
myTile.LockTile();
}
}
protected bool TileValidity(Transform tile)
{
if (myTile != null)
{
if (myTile.transform == tile) // we've selected the tile we are standing on
return false;
}
return tileMaster.CheckTilesInRange(tile.name); // ALWAYS RETURNS FALSE
}
}
From here I want to check to see if the tile that’s been hit is within a dictionary of other tiles
public class TileMaster : MonoBehaviour
{
Dictionary<string, GameObject> activeTiles = new Dictionary<string, GameObject>();
protected SphereCollider tileTrigger;
GameObject selectionTile;
bool PlayerIsMoving;
private void Start()
{
selectionTile = transform.GetChild(0).gameObject;
tileTrigger = GameObject.FindGameObjectWithTag("TileTrigger").GetComponent<SphereCollider>();
}
protected void AddTile(string name, GameObject rangeObject)
{
if(PlayerIsMoving)
rangeObject.SetActive(false);
else
rangeObject.SetActive(true);
activeTiles.Add(name, rangeObject);
}
protected void RemoveTile(string keyName)
{
int count = 0;
foreach (KeyValuePair<string, GameObject> tile in activeTiles)
{
if (tile.Key == keyName)
{
count += 1;
break;
}
}
if(count > 0)
{
activeTiles[keyName].SetActive(false);
activeTiles.Remove(keyName);
}
}
public void HideAllTiles()
{
PlayerIsMoving = true;
selectionTile.SetActive(false);
foreach (KeyValuePair<string, GameObject> tile in activeTiles)
{
tile.Value.SetActive(false);
}
}
public void UnhideAllTiles()
{
PlayerIsMoving = false;
foreach (KeyValuePair<string, GameObject> tile in activeTiles)
{
tile.Value.SetActive(true);
}
}
public bool CheckTilesInRange(string keyName)
{
foreach (KeyValuePair<string, GameObject> item in activeTiles)
{
if (item.Key == keyName) // A DEBUG ANYWHERE IN THIS LOOP NEVER RUNS
return true;
}
return false;
}
public void EnableSelectionTile(Vector3 tilePosition, string tileName)
{
foreach (KeyValuePair<string, GameObject> tile in activeTiles)
{
if (tile.Key == tileName)
tile.Value.SetActive(false);
}
selectionTile.transform.position = tilePosition;
selectionTile.SetActive(true);
}
public void DisableSelectionTile()
{
foreach (KeyValuePair<string, GameObject> tile in activeTiles)
{
if (!tile.Value.activeSelf)
tile.Value.SetActive(true);
}
selectionTile.SetActive(false);
}
}
and tiles are added to the dictionary when they collide with a trigger that follows the player - TileController inherits from the above
public class TileController : TileMaster
{
[SerializeField]
GameObject rangeObject;
[HideInInspector]
public bool locked;
[HideInInspector]
public bool active;
public void LockTile()
{
locked = true;
active = false;
RemoveTile(name);
if (rangeObject.activeSelf)
rangeObject.SetActive(false);
}
public void UnlockTile()
{
locked = false;
if (Vector3.Distance(transform.position, tileTrigger.transform.position) < tileTrigger.radius)
{
AddTile(name, rangeObject);
active = true;
}
else
{
RemoveTile(name);
active = false;
}
}
private void OnTriggerEnter(Collider other)
{
switch(other.tag)
{
case "TileTrigger":
if(!locked)
{
active = true;
AddTile(name, rangeObject);
}
break;
default:
break;
}
}
private void OnTriggerExit(Collider other)
{
switch (other.tag)
{
case "TileTrigger":
active = false;
RemoveTile(name);
break;
default:
break;
}
}
}
but for whatever reason, CheckTilesInRange(string keyName) always returns false, and if a debug is placed within the FOREACH, nothing debugs… IE
public bool CheckTilesInRange(string keyName)
{
foreach (KeyValuePair<string, GameObject> item in activeTiles)
{
Debug.Log("HIT");
if (item.Key == keyName)
return true;
}
return false;
}
Console will never debug “HIT”
I’m guessing I don’t fully understand inheritance, as I seem to be having trouble setting a simple bool PlayerIsMoving; – this is supposed to be set when the player Move() function is called in sript 1, HideAllTiles() is supposed to set PlayerIsMoving within TileMaster to true, but even that debugs as false