Search Unity

Programmatically determining desired player target from directional inputs

Discussion in 'Scripting' started by Sendatsu_Yoshimitsu, Nov 27, 2014.

  1. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    So in my continuing quest to refine a third-person brawler-esque combat system I've jumped through several iterations, starting with collision detection and eventually leading to using messaging plus the dot product of the player and enemy to figure out if your facing matches well enough to constitute a hit:

    Code (csharp):
    1.  
    2. float distanceToTarget = Vector3.Distance(transform.position + new Vector3 (0,1,0), defenderList[i].gameObject.transform.position);  
    3.          directionToTarget = (defenderList[i].gameObject.transform.position - transform.position).normalized;
    4.          directionToTarget.y = 0;
    5.          if (Input.GetAxis ("Horizontal") == 0 && Input.GetAxis ("Vertical") == 0){     //If the player isn't holding any movement key
    6.            playerAttackAngle = Vector3.Dot(directionToTarget, transform.forward);     //Take the dot product of the direction to target +  player's forward
    7.          }
    8.          else{                                       //If the player IS holding a movement key
    9.  
    10.            playerAttackAngle = Vector3.Dot(directionToTarget.normalized,  (new Vector3(Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"))).normalized );     //Take the dot product of the direction to target plus the direction of the vector formed by the WSAD keys the player is holding
    11.          }
    12.          if (distanceToTarget <= attack.range && (playerAttackAngle > attack.areaOfEffect)){         //Double check that enemy is in range, and inside the player's attack cone
    13.            //Message enemy that they've been hit
    14.          }
    This has the closest feel to what I'm trying to achieve of anything I've tried, but it's still not quite right: you spend an awful lot of time futzing around to get your facing just right, and the controls that give you the most freedom and utility from this system is a very PS1-esque 8-direction movement system which doesn't feel right in the non-combat sections.

    As I take a closer look at a lot of the games who have the feel I'm trying to achieve (arkham asylum, asscreed, yakuza, godhand), I'm realizing that they really don't have aiming at all: instead of making orienting yourself to your enemies into a gameplay challenge, they use very subtle soft lock-on to ensure that unless you're facing an extremely weird direction with nothing in it, you will hit anything within range and in the general direction you're moving or holding the movement keys in. To that end I'm rethinking my approach, and I realized that I might not actually need much data about their physical location at all: I need distance + line of sight to ensure they're hit-able, but once I have that my big task isn't checking the player's facing, it's checking his inputs: if I'm holding W and nothing else when I attack, I should hit the closest guy directly in front of me. If I'm holding D, I should pivot and hit the guy to my right. If I'm holding W + D, I should hit the closest enemy between my 12-3 o'clock.

    This seems much cleaner, faster, and less error-prone than what I've been doing, but I'm struggling with how to actually implement it: given a list with every enemy that is both in range and in line of sight to the player, and given the control inputs, is there an easy way to determine which of the enemies (if any) I'm trying to hit?