1. Can anyone help me with a code example of how to detect the player being on the ground in C# ?
     
  2. Pseudo code:
    Code:
    BasePlayer player;
    if (player.IsOnGround())
    {
        //do something
    }
     
  3. Thanks for the code I see that in r-AntiCheat but it seems to return true no matter what I'm standing on.
    Code:
    Puts($"player.IsOnGround() = {player.IsOnGround().ToString()}");
     
  4. Oh you want to only detect whether a player is standing on terrain? I guess, in addition to the IsOnGround() check, you could then ray cast downwards from the player position and determine on what he is standing on. I didn't really look into it besides the IsOnGround() check, so I might be talking out of my ass here, though.
     
  5. ^Yes.

    I don't really know how to, "ray cast downwards from the player position and determine on what he is standing on"
     
  6. Code:
    bool IsOnTerrain(BasePlayer player)
    {
        if (!player.IsOnGround()) return false; // if the player isn't grounded we don't need to do anything special    RaycastHit hit;    // if he is grounded we need to raycast down and if we hit something (which we should anyways, since we are grounded) output the raycast hit into hit
        if (Physics.Raycast(player.transform.position, Vector3.down, out hit))
        {
            // now that we hit something we can further determine what we hit and act accordingly
            // we determine whether we hit the "Terrain" (actual ground) layer or the "World" (rocks, radtown buildings, etc.) layer
            if (hit.collider.gameObject.layer == LayerMask.NameToLayer("Terrain") || hit.collider.gameObject.layer == LayerMask.NameToLayer("World"))
            {
                return true; // if we indeed hit either the "Terrain" or the "World" layer we return true
            }
        }
        return false; // if we didn't yet return a value we return false
    }
    I do think it would have been better to steer you into the right direction instead of writing down the code but it's kind of late over here and I need to sleep.

    I used the following resources to put the code above together:

    To get the names of the LayerMasks Rust uses I looked at this plugin:
    I'm aware that there are other ways to acquire the names of the LayerMasks Rust uses but it was the quickest for me.

    To get more information on how to properly work with LayerMasks and RayCasts I used:
    I hope everything works as intended. I did test the function above briefly on my local server and the behavior seems to be correct. Glad I could help.
     
  7. AWESOME ! Thanks! :)
     
  8. Here's a version which is slightly more compact but kind of sacrifices readability:
    Code:
    bool IsOnTerrain(BasePlayer player)
    {
        return !(!player.IsOnGround() || Physics.Raycast(player.transform.position, Vector3.down, Mathf.Infinity, ~LayerMask.GetMask("Terrain", "World", "Water")));
    }
    One thing I noticed is that certain parts of Radtowns are in the "Default" LayerMask. This posses a problem because we can't just include the "Default" LayerMask because deployables are also under the "Default" LayerMask. This kind of makes this IsOnTerrain(...) check a bit unreliable! Oh well.
     
  9. Is there another way to detect if a player is in the Radtown.
     
  10. I tried some things but I couldn't find a straight-forward way.
     
  11. Better way for you will check on collider name without any RT checks:

    Code:
    bool IsOnTerrain(BasePlayer player)
    {
        if (!player.IsOnGround()) return false;    RaycastHit hit;    if (Physics.Raycast(player.transform.position, Vector3.down, out hit))
        {
             if (hit.collider.name.Equals("Terrain"))
             {
                return true;
             }
        }
        return false;
    }
     
    Last edited by a moderator: Mar 7, 2016
  12. Sadly this won't work for larger rocks because their "hit.collider.name" is "Mesh".
    It won't work for Radtown buildings either because their "hit.collider.name" is specific to the actual building, e.g. "industrial_bld_j" or "sewer_drainwall_1800".
    [DOUBLEPOST=1457367278][/DOUBLEPOST]Because Facepunch recently started to keep track of the OwnerIDs of Entitys, we can check if the OwnerID of something we hit is not 0 (meaning it's probably assigned to a player and hence built by a player) and that way determine if people are on Terrain or not. This fixes the Radtown issue.
    Code:
    bool IsOnTerrain(BasePlayer player)
    {
        if (!player.IsOnGround()) return false;    RaycastHit hit;    if (Physics.Raycast(player.transform.position + player.GetOffset(), Vector3.down, out hit, player.GetHeight(), ~LayerMask.GetMask("Terrain", "World", "Water")))
        {
            if (hit.GetEntity() != null && hit.GetEntity().OwnerID != 0)
            {
                return false;
            }
        }
        return true;
    }
    This seems to be the most reliable way. There are still some edge-cases if someone is standing on the edge of a foundation the ray will miss the actual foundation and tell you that the player is standing on "Terrain" but that's not really that big of a deal, I assume.
     
    Last edited by a moderator: Mar 7, 2016
  13. Oh, well, okay.

    Also, if somebody is need:
    Code:
    bool isOnRT(Vector3 position)
    {
                var allColliders = Physics.OverlapSphere(position, 0);            foreach (Collider collider in allColliders)
                {
                    if (collider.name.Contains("prevent_building") && collider.gameObject.ToBaseEntity() == null) 
                        return true;
                }            return false;
    }
     
  14. Great thanks !