Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Vector3.Distance always returns true

Discussion in 'Scripting' started by Ceders, May 25, 2020.

  1. Ceders

    Ceders

    Joined:
    May 17, 2020
    Posts:
    2
    Hi all,

    I can't figure out where the bug in my code is, please help a beginner :)

    Currently when I run the game, I can attack from any distance even though I am trying to set a range of 60 units.

    Code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Security.Cryptography;
    4. using UnityEngine;
    5.  
    6. public class UserStats : MonoBehaviour
    7. {
    8.  
    9.     public string username;
    10.     public int level;
    11.     public string UserClass;
    12.  
    13.     public float curHp;
    14.     public float maxHp;
    15.     public float curMp;
    16.     public float maxMp;
    17.  
    18.     public float baseAttackPower;
    19.     public float curAttackPower;
    20.     public float baseAttackSpeed;
    21.     public float curAttackSpeed;
    22.     public float baseDodge;
    23.     public float curDodge;
    24.     public float baseHitPercent;
    25.     public float curHitPercent;
    26.  
    27.     public float hpRegenTimer;
    28.     public float hpRegenAmount;
    29.     public float mpRegenTimer;
    30.     public float mpRegenAmount;
    31.  
    32.     public float curXp;
    33.     public float maxXp;
    34.  
    35.     public bool isDead;
    36.  
    37.     public GameObject selectedUnit;
    38.  
    39.     public EnemyStats enemyStatsScript;
    40.  
    41.     public bool behindEnemy;
    42.     public bool canAttack;
    43.  
    44.     public float autoAttackCooldown;
    45.     public float autoAttackCurTime;
    46.  
    47.  
    48.     // Start is called before the first frame update
    49.     void Start()
    50.     {
    51.        
    52.     }
    53.  
    54.     // Update is called once per frame
    55.     void Update()
    56.     {
    57.         if (Input.GetMouseButtonDown(0))
    58.         {
    59.             SelectTarget();
    60.         }
    61.  
    62.         if (selectedUnit != null)
    63.         {
    64.             Vector3 toTarget = (selectedUnit.transform.position - transform.position).normalized;
    65.             //Check if player is behind Enemy ( Calculate Dodge, Parry, extra damage, etc.)
    66.             if (Vector3.Dot(toTarget, selectedUnit.transform.forward) < 0)
    67.             {
    68.                 behindEnemy = false;    //Implement better hitchance, critchance, worse dodge etc.
    69.             }
    70.             else
    71.             {
    72.                 behindEnemy = true;
    73.             }
    74.  
    75.             //Calculate if the player is facing the enemy and is within attack distance
    76.             float distance = Vector3.Distance(this.transform.position, selectedUnit.transform.position);
    77.             Vector3 targetDir = selectedUnit.transform.position - transform.position;
    78.             Vector3 forward = transform.forward;
    79.             float angle = Vector3.Angle(targetDir, forward);
    80.  
    81.             if (angle > 60.0)
    82.             {
    83.                 canAttack = false;
    84.             }
    85.             else
    86.             {
    87.                 if (distance < 60)  //TODO:FIX, currently attacks at any distance
    88.                 {
    89.                     canAttack = true;
    90.                 }
    91.                 else
    92.                 {
    93.                     canAttack = false;
    94.                 }
    95.             }
    96.         }
    97.         if (Input.GetKeyDown("1"))
    98.         {
    99.             //TODO: make sure player is facing enemy and is in range
    100.             if (selectedUnit != null && canAttack)
    101.             {
    102.                 BasicAttack();
    103.             }
    104.         }
    105.  
    106.         //TODO: Ranged spell attack
    107.     }
    108.     void SelectTarget()
    109.     {
    110.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    111.         RaycastHit hit;
    112.  
    113.         if(Physics.Raycast(ray, out hit, 10000))
    114.         {
    115.             if(hit.transform.tag == "Enemy")        //Duplicate this if-statement for each type, i.e. Ally, Neutral, Villager, whatever
    116.             {
    117.                 selectedUnit = hit.transform.gameObject;
    118.  
    119.                 enemyStatsScript = selectedUnit.transform.gameObject.transform.GetComponent<EnemyStats>();
    120.             }
    121.         }
    122.     }
    123.  
    124.     void BasicAttack()
    125.     {
    126.         //TODO: Animation
    127.         enemyStatsScript.ReceiveDamage(10);
    128.     }
    129. }
    130.  



    Would really appreciate any help as well as pointers as how to improve my code/efficiency as I have no clue, thanks!
     
  2. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    637
    If you put a debug log right above
    canAttack = true;
    , what does it print?
    To avoid clutter inside the console, you could also set a public field to the distance like so:
    debugDistanceValue = distance;
    right after
     float distance = Vector3.Distance


    Code efficiency ... well, if want it hard coded, search for "StateMachine" - this way you can create states like Idle, Attacking, Searching and handle all code inside those states which reduces the clutter in one file.

    Also when writing proper object oriented code, you want to avoid making all fields public. Instead only set the fields public that you want to access from other classes/scrips. To make them still visible in the Editor use the
    [SerializeField]
    Attribute
    https://docs.unity3d.com/ScriptReference/SerializeField.html

    Also "UserStats" does not seem like the right name, this script attacks units and checks positions and does a lot of things I would not describe as "UserStats" - maybe you want to create a second script for all those actions and call it "AttackScript" or something that represents better what is happening in the script.
     
    Ceders likes this.
  3. Ceders

    Ceders

    Joined:
    May 17, 2020
    Posts:
    2
    Thank you so much Hannibal_leo! Turns out the code is working fine, my scale is just not what I thought it was. So I just need to tone down the distance and voila!

    Will check out StateMachines and Serializing Fields, thank you!