Jump to content
  • Advertisement
Sign in to follow this  
steviebops

Unity Stealth system

This topic is 1952 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been working on a Tenchu-style stealth system, and I've run into a problem.
I use Unity, and asked over there, but I'm not getting a solution.


My problem is when the player presses their back against a wall, in this case a cube. I can only get the player to face (away) parallel with one side of the cube, by using the camera, on the other sides, I can't figure out how to do it.
Has anyone here a solution please?


 


var dir = transform.TransformDirection(Vector3.forward);        
        Debug.DrawRay(transform.position, dir * distanceToWall, Color.blue);
        if (Physics.Raycast(transform.position, dir, out hit, distanceToWall))
        {
            if (hit.collider.gameObject.tag == "Sneaking Volumes")
            {
                if (animation.IsPlaying("P1TurnAgainstWall"))
                {
                    animation.CrossFade("P1WallHideStand", 1.0f);
 
                    TPController.characterController.Move(-hit.normal);
                   
                    transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x,
                   Mathf.Lerp(transform.rotation.eulerAngles.y,
                    Camera.mainCamera.transform.eulerAngles.y,
                   .5f),
                   transform.rotation.eulerAngles.z);
                    TPController.characterController.radius = .3f;                  
                }
            }
        }

 

 

 

 

Share this post


Link to post
Share on other sites
Advertisement

Not sure I understand the question... do you mean rotating the character swings the camera round so it is looking through the wrong side of the wall? Do you want the player to be seen face on with his back against the wall?

 

What you should probably do in that case is not turn the character in code at all (except to align it to the wall as a lead in to the animation), put the rotation of the character into the animation instead, and keep the character facing to be towards the wall in the code. That would be more natural for controlling the character as well (i.e. you don't want the controls to flip left/right when you are leaning against a wall either).

Share this post


Link to post
Share on other sites

I have an animation that turns the player 180°back against the wall, the problem is locking the rotation when he's touching the wall.

The character rotates to snap to the camera direction for general movement.

With the animation, the player will face away from the wall, but will rotate with the camera.
 

transform.rotation = Quaternion.Euler(transform.eulerAngles.x,
                                                  Camera.mainCamera.transform.eulerAngles.y,
                                                  transform.eulerAngles.z);

 

After he locks to the wall

 

if (TPAnimator.Instance.State == TPAnimator.CharacterState.PressedWallStand)
        {
            if (animation.IsPlaying("P1WallHideStand"))
            {
                transform.rotation = Quaternion.Euler(transform.eulerAngles.x,
                                                  0,
                                                  transform.eulerAngles.z);
            }
        }

 

By replacing the camera's y transform, I think I can get the correct angle for each face, the above example, 0, only allows the character to face one way, with no y rotation.
It's not related to the cube sides, it'll work facing one side, but will be sideway or backwards on the others.

 

I can't figure out how to get the character to be parallel with each side, then stay that way.
 

Share this post


Link to post
Share on other sites

You need to use the normal of the cube face you are stealthing upon, you can probably extract that from the collision data you get back from your raycast.

 

I wouldn't use Euler angles for this though, use vectors. You want to slerp your rotation to align with the normal of the cube face. If you must use Eulers, you need to convert the returned normal into an Euler angle representation.

Share this post


Link to post
Share on other sites

Yup, that seems to have done it biggrin.png 

I use this code 

 

if (TPAnimator.Instance.State == TPAnimator.CharacterState.PressedWallStand)
        {
            if (animation.IsPlaying("P1WallHideStand"))
            {
                  transform.rotation = Quaternion.FromToRotation(-transform.forward, TPAnimator.Instance.hit.normal) * transform.rotation;
            }
        }

 

And it seems fine so far. The collision stops the player from moving into the cube, and Ill add code later to stop them from pulling away without hitting the right button, or stealthing past edges.

thanks for the help!!

Share this post


Link to post
Share on other sites
Im not sure how to stop the player from sneaking past the end of the wall(cube face).
Is there some way to get the length of the wall from the raycast hit? I could then probably limit movement while standing at the wall to some value of just less than that length.

Share this post


Link to post
Share on other sites

Im not sure how to stop the player from sneaking past the end of the wall(cube face).
Is there some way to get the length of the wall from the raycast hit? I could then probably limit movement while standing at the wall to some value of just less than that length.

you could just do a raycast towards the wall (opposite direction of the normal) from the position the character is moving towards, then check that it hits the same object as a raycast from its current position.

Share this post


Link to post
Share on other sites

The character already has their back to the wall, and are moving along it sideways. What Im trying to determine is, is it possible to get the length of that wall.
I have attached a picture to show the situation.[attachment=15741:WallProblem.png]
 

Share this post


Link to post
Share on other sites

The character already has their back to the wall, and are moving along it sideways. What Im trying to determine is, is it possible to get the length of that wall.
I have attached a picture to show the situation.attachicon.gifWallProblem.png
 

 

you could get the dimensions of the collider your ray hits, or of the object it belongs to. if your wall colliders/objects have complex shapes it gets a bit tricky though.

 

The raycast method is probably the easiest way to do it with Unity though and it makes it very easy to deal with complex shaped walls. (the raycast from a the target position lets you know if you're about to move off the edge, how much the wall curves, etc).

 

You could also add a separate layer with colliders extending from the wall edges and only use that layer when the character is sneaking along walls. (For complex levels adding all those extra colliders could take quite alot of effort though but its easy to code (just use http://docs.unity3d.com/Documentation/ScriptReference/Physics.IgnoreLayerCollision.html)

Edited by SimonForsman

Share this post


Link to post
Share on other sites

I might do the extra collision volume method. I've messed around with getting the dimensions from the collider, it's not working as of yet. Ill try again tomorrow.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!