Hello again,
Hit a bit of a roadblock during the Final Polish sections of the Combat Creator course and I could do with some help addressing the problem.
I’m at the point in the lesson where we start to introduce Generic Rayastables for the InteractWithComponent method.
From what I can tell I’ve written the code more or less identical to what is presented in the lesson, except for replacing PlayerController with MyPlayerControlller in the IRaycastable interface and the relevant references.
As it stands - I have differennt cursors working for UI, Movement and Combat but when I hover over an item - the cursor does not change and the item is not picked up.
I cant click to move to the item location either.
I’ve checked the layer for my item pickup and its set as default.
I’m not really sure how to debug this.
Any tips would be greatly appreciated.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using RPG.Movement;
using RPG.Combat;
using RPG.Attributes;
using UnityEngine.EventSystems;
namespace RPG.Control
{
public class MyPlayerController : MonoBehaviour
{
Health health;
enum CursorType
{
None,
Movement,
Combat,
UI
}
[System.Serializable]
struct CursorMapping
{
public CursorType type;
public Texture2D texture;
public Vector2 hotspot;
}
[SerializeField] CursorMapping[] cursorMappings = null;
private void Awake()
{
health = GetComponent<Health>();
}
private void Update()
{
if (InteractWithUI()) return;
if (health.IsDead())
{
SetCursor(CursorType.None);
return;
}
if (InteractWithComponent()) return;
if (InteractWithCombat()) return;
if (InteractWithMovement()) return;
SetCursor(CursorType.None);
}
private bool InteractWithUI()
{
if (EventSystem.current.IsPointerOverGameObject())
{
SetCursor(CursorType.UI);
return true;
}
return false;
}
private bool InteractWithComponent()
{
RaycastHit[] hits = Physics.RaycastAll(GetMouseRay());
foreach (RaycastHit hit in hits)
{
IRaycastable[] raycastables = hit.transform.GetComponents<IRaycastable>();
foreach (IRaycastable raycastable in raycastables)
{
if (raycastable.HandleRaycast(this))
{
SetCursor(CursorType.Combat);
return true;
}
}
}
return false;
}
private bool InteractWithCombat()
{
RaycastHit[] hits = Physics.RaycastAll(GetMouseRay());
foreach (RaycastHit hit in hits)
{
CombatTarget target = hit.transform.GetComponent<CombatTarget>();
if (target == null) continue;
if (!GetComponent<Fighter>().CanAttack(target.gameObject))
{
continue;
}
if (Input.GetMouseButton(0))
{
GetComponent<Fighter>().Attack(target.gameObject);
}
SetCursor(CursorType.Combat);
return true;
}
return false;
}
private bool InteractWithMovement()
{
RaycastHit hit;
bool hasHit = Physics.Raycast(GetMouseRay(), out hit);
if (hasHit)
{
if (Input.GetMouseButton(0))
{
GetComponent<Mover>().StartMoveAction(hit.point, 1f);
}
SetCursor(CursorType.Movement);
return true;
}
return false;
}
private void SetCursor(CursorType type)
{
CursorMapping mapping = GetCursorMapping(type);
Cursor.SetCursor(mapping.texture, mapping.hotspot, CursorMode.Auto);
}
private CursorMapping GetCursorMapping(CursorType type)
{
foreach (CursorMapping mapping in cursorMappings)
{
if (mapping.type == type)
{
return mapping;
}
}
return cursorMappings[0];
}
private static Ray GetMouseRay()
{
return Camera.main.ScreenPointToRay(Input.mousePosition);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPG.Control;
namespace RPG.Combat
{
public class WeaponPickup : MonoBehaviour, IRaycastable
{
[SerializeField] Weapon weapon = null;
[SerializeField] float respawnTime = 5f;
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
//Debug.Log("Testy");
Pickup(other.GetComponent<Fighter>());
}
}
private void Pickup(Fighter fighter)
{
fighter.EquipWeapon(weapon);
StartCoroutine(HideForSeconds(respawnTime));
}
private IEnumerator HideForSeconds(float seconds)
{
ShowPickup(false);
yield return new WaitForSeconds(seconds);
ShowPickup(true);
}
private void ShowPickup(bool shouldShow)
{
GetComponent<Collider>().enabled = shouldShow;
foreach (Transform child in transform)
{
child.gameObject.SetActive(shouldShow);
}
}
public bool HandleRaycast(MyPlayerController callingController)
{
if (Input.GetMouseButtonDown(0))
{
Pickup(callingController.GetComponent<Fighter>());
}
return true;
}
}
}
namespace RPG.Control
{
public interface IRaycastable
{
bool HandleRaycast(MyPlayerController callingController);
}
}