Passing animation state into attack method
Hey Unity family!
I've been teaching myself programming (with unity learn premium being free through the next few months and all), and I'm currently working on an Isometric ARPG with a friend. I've got a player controller working to the point where if I hold/or click the left mouse button down my character will move about the world, and if I do the same for the right click he'll interact with objects. What I'd like to get working is firstly, having my first attack be triggered by the left click, and my second attack be triggered by the right.
Right now movement looks like this:
public class PlayerController : MonoBehaviour
{
public Interactable focus;
public LayerMask movementMask;
Camera cam;
PlayerMotor motor;
Animator anim;
NavMeshAgent agent;
[SerializeField] float animSpeed =1f;
private void Start() {
cam = Camera.main;
motor = GetComponent<PlayerMotor>();
anim = GetComponentInChildren<Animator>();
}
private void Update() {
if(EventSystem.current.IsPointerOverGameObject())
return;
//left mouse butotn press actions:
if (Input.GetMouseButton(0))
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast (ray, out hit, 100, movementMask)) //if we left click on the ground we'll move to it
{
motor.MoveToPoint(hit.point);
//remove focus
RemoveFocus(); // if we click on the ground after click on an enemy/item we'll stop going to them and go to our new ground point
}
}
//right mouse button press actions:
if (Input.GetMouseButton(1))
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast (ray, out hit, 100))
{
Interactable interactable = hit.collider.GetComponent<Interactable>();
if (interactable != null)
{
SetFocus(interactable);
}
}
}
/*attacks are currently bound to alpha1/2 so I could play test colliders */
if(Input.GetButtonDown("MainAttack"))
{
anim.SetTrigger("Attack1");
}
if(Input.GetButtonDown("SecondaryAttack"))
{
anim.SetTrigger("Attack2");
}
}
// these control focusing our player. If I right click an enemy/object he'll go and attack it, or interact with it as applicable (e.g. pick it p).
void SetFocus(Interactable newFocus)
{
if(newFocus != focus)
{
if(focus != null)
focus.OnDefocused();
focus = newFocus;
motor.FollowTarget(newFocus);
}
newFocus.OnFocused(transform);
}
void RemoveFocus()
{
if(focus != null)
focus.OnDefocused();
focus = null;
motor.StopFollowingTarget();
}
}
So as you can see above I move/interact with the mouse and have bound the attacks to number keys to debug/work on collider size etc. I'd like the leftmouse button to move when clicked over the ground, and do attack1 when over an enemy/destructible object. The right click should do attack2 over an enemy, and otherwise interact with objects (destroy them, pick up loot, talk to NPCs, and open doors etc).
The player interacts with objects/enemies/etc via making an "interactable" class, and deriving different interactable subclasses from it:
public class Interactable : MonoBehaviour
{
public float radius = 3f; //this will act as a "pickup" radius - instead of just relying on colliders. needs access from other scripts
public Transform interactionTransform; // I'm adding these as separate gameObjects on any lootable item called "interaction transform target". its only useable if we want the player to approach certain interactables from a certain position (think doors or chests)
bool isFocus = false;
Transform player;
GameObject playerGameObject;
bool hasInteracted = false;
public virtual void Interact()
{
// this method is meant to be overwritten by different interactable classes
Debug.Log("Interacting with " + transform.name);
}
void Update()
{
if(isFocus && !hasInteracted)
{
float distance = Vector3.Distance(player.position, interactionTransform.position);
if(distance <= radius)
{
Interact();
hasInteracted = true;
}
}
}
public void OnFocused(Transform playerTransform)
{
isFocus = true;
player = playerTransform;
hasInteracted = false;
}
public void OnDefocused()
{
isFocus = false;
player = null;
hasInteracted = false;
}
private void OnDrawGizmosSelected()
{
if(interactionTransform == null)
interactionTransform = transform;
Gizmos.color = Color.green;
Gizmos.DrawWireSphere(interactionTransform.position, radius);
}
}
the current interactble class I'm working with looks like this:
public class Destructible : Interactable
{
PlayerManager playerManager;
CharacterCombat playerCombat;
public Rigidbody lootPrefab;
public Transform spawner;
public GameObject destructibleVersion;
public float spawnForce; // debugging how hard items should spawn into the world (currently doesn't do much)
private void Start() {
playerManager = PlayerManager.instance;
playerCombat = playerManager.GetComponent<CharacterCombat>();
}
public override void Interact()
{
base.Interact(); //calls the base functions of the function we're overriding
HitMe();
}
void HitMe()
{
playerCombat.PlayerAttack(); /* This calls to another derived class and triggers an attack. I want to pass in whichever attack I have attacked this object with. as so far I have to make that method call a specific attack*/
}
private void OnTriggerEnter(Collider other)
{
if(other.tag == "Weapon") //will now only destroy when connected with the collider I created for the sword in our players hand.
{
Rigidbody lootInstance; //
lootInstance = Instantiate(lootPrefab, spawner.position, spawner.rotation) as Rigidbody;
Instantiate(destructibleVersion, transform.position, transform.rotation);
lootPrefab.AddForce(spawner.up);
Destroy(this.gameObject);
}
}
}
As shown in the /**/ note in the method directly above the destructilbe item will call "PlayerAttack()" in this method:
public class CharacterCombat : MonoBehaviour
{
PlayerManager playerManager;
Animator anim;
// Start is called before the first frame update
void Start()
{
playerManager = PlayerManager.instance;
anim = playerManager.playerAnimator;
}
public void PlayerAttack()
{
anim.SetTrigger("Attack1");
}
}
What I want to be able to do is pass in the attack (attack1 or attack2) into this last method. So my player will run up and do whichever attack I told it to to the object, rather than (as it is now) hardcoding one or the other attack to it.
If anyone responds, thanks so much! If something's unclear just let me know!
Your answer
Follow this Question
Related Questions
Problem making my character walk backward 0 Answers
Shoot towards mouse except mouse y 1 Answer
Can't get raycast to mousePosition 0 Answers