Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by Maijin · Mar 11, 2015 at 01:42 PM · movementspace shootermathf.clampboundary

Little problem with Mathf.Clamp as used in Space Shooter Tutorial

Hi, I'm new to Unity and programming in general, when possible i follow tutorials and try to get answers to my noob questions googling and hoping someone had the same issue before, but this time I couldn't find any answer solving a similar problem.

In the Space Shooter Unity tutorial, the movement of the spaceship is bound to the camera view by using the Mathf.Clamp function. This is the code:

 [System.Serializable]
 public class Boundary
 {
     public float xMin, xMax, zMin, zMax;
 }
 
 public class PlayerController : MonoBehaviour 
 {
     public float speed;
     public Rigidbody rb;
     public Boundary boundary;
 
     void FixedUpdate () 
     {
         float moveHorizontal = Input.GetAxis ("Horizontal");
         float moveVertical = Input.GetAxis ("Vertical");
         Vector3 movement = new Vector3 (moveHorizontal, 0.0F, moveVertical);
         rb.velocity = movement * speed;
 
         rb.position = new Vector3
         (
             Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax),
             0.0F,
             Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax)
         );
     }
 }

The Rigidbody is attached to the spaceship 3D model, and the xMin, xMax, zMin, zMax and speed values are user-defined in the inspector.

Now the code works almost perfectly, with the exception that, when reaching the border limits (e.g.. -6 and 6 in the x axis), the spaceship slightly overlaps this limit (-6.2, 6.2), returning to the limit values when you stop pressing the movement buttons. The excess movement (over the bounds) is affected by changing the speed amount, so i guess it must be something related to Physics, RigidBody, velocity or similar...

I guess if there's a way to limit the movement exactly to the values in the Mathf.Clamp function or if a total different approach has to be used.

Thanks in advance.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image savlon · Mar 11, 2015 at 01:48 PM 0
Share

Have a look at this method of clamping to screen bounds... It may be a better way to do it than hard coding the coordinates https://www.youtube.com/watch?v=mq4BlZLRe$$anonymous$$k

avatar image Maijin · Mar 11, 2015 at 07:05 PM 0
Share

Thanks for the link. Honestly it's a bit too much for my actual basic skills. I started learning a bit of Flash before deciding to switch to Unity, and in AS3 there was no easy solution like the one adopted in the Space Shooter tutorial, so i wanted to understand if the imbedded Unity functions could do this job correctly, though i understand if you have the skills to code everything your own way, then you can get way more than simply using prefab functions. I'll keep the link to this video for future projects ;)

avatar image illogicalcrow · Mar 11, 2015 at 07:06 PM 0
Share

When you run it in editor does the actual transform of the spaceship exceed the boundary (check the inspector)? The boundary doesn't look like it's adjusting for the actual size of player's model. The transform position is an infinitely small point, so a model centered on this point will have about half cross whatever the clamped values are.

9 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by fffMalzbier · Mar 11, 2015 at 02:12 PM

Mathf.Clamp does his job fine. The problem is that in the inspector you see the position of the transform but you are not clamping the position of the transform but the position of the rigidity body.

In the FixedUpdate function is called more often and not in the same cycle like the normal Update function that can cause some interesting behavior if you set the / read the position.

If you are really need to clamp the transform position you can add this to your script (but in in the tutorial you should be fine without it):

     void Update()
     {
         transform.position = new Vector3 
             (
                 Mathf.Clamp (rigidbody.position.x, boundary.xMin, boundary.xMax), 
                 0.0f, 
                 Mathf.Clamp (rigidbody.position.z, boundary.zMin, boundary.zMax)
                 );
     }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Maijin · Mar 11, 2015 at 06:48 PM 0
Share

Thanks.

I previously tried your code (line 3 - transform.position ins$$anonymous$$d of rb.position) in the FixedUpdate() function but nothing changed from the original tutorial code that i pasted, so i guessed it was another issue.

The same code inside an Update() function works as you suggested, and the bounds are never overlapped respecting the figures of -6 and 6.

Though i don't yet clearly understand the reason of this different behavior when the same code is added in Update() ins$$anonymous$$d of FixedUpdate() i guess i'll better understand with a bit more of experience.

avatar image fffMalzbier · Mar 11, 2015 at 09:39 PM 0
Share

This page can help you to understand in what order and how the update routines are called http://docs.unity3d.com/$$anonymous$$anual/ExecutionOrder.html

avatar image
1

Answer by Darkskyb2 · Nov 03, 2016 at 07:38 PM

This is my code and it's working fine. Hope it helps

 using UnityEngine;
 using System.Collections;
 
 [System.Serializable]
 public class Boundary 
 {
     public float xMin, xMax, zMin, zMax;
 }
 
 public class PlayerController : MonoBehaviour 
 {
 
     private Rigidbody rb;
     public float speed;
     public float tilt;
     public Boundary boundary;
     private AudioSource audio;
 
     public GameObject shot;
     public Transform ShotSpawn;
     public float fireRate;
 
     private float nextFire;
 
     void Start() {
         
         rb = GetComponent<Rigidbody> ();
         audio = GetComponent<AudioSource> ();
     }
 
     void Update() 
     {
         if (Input.GetButton ("Fire1") && Time.time > nextFire) {
             nextFire = Time.time + fireRate;
             Instantiate (shot, ShotSpawn.position, ShotSpawn.rotation);
             audio.Play ();
         }
         
     }
 
     void FixedUpdate() 
     {
         float moveHorizontal = Input.GetAxis ("Mouse X");
         float moveVertical = Input.GetAxis ("Mouse Y");
 
         Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
         rb.AddForce (movement * speed);
 
         rb.position = new Vector3 (
 
             Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax), 
             0.0f,
             Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax)
         ); 
 
         rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -tilt);
 
         DecelerateWhenHittingXBorders();
         DecelerateWhenHittingZBorders();
 
     }
 
     void DecelerateWhenHittingXBorders()
     {
         if (rb.position.x >= boundary.xMax || rb.position.x <= boundary.xMin) {
             //reduce velocity indirectly by force
             //rb.AddForce(-speed * rb.velocity.x, 0, 0);
 
             //reduce velocity directly
             rb.velocity -= new Vector3 (rb.velocity.x / 3f, 0, 0);
         }
     }
 
     void DecelerateWhenHittingZBorders()
     {
         if (rb.position.z >= boundary.zMax || rb.position.z <= boundary.zMin) {
             //reduce velocity indirectly by force
             //rb.AddForce(-speed * rb.velocity.x, 0, 0);
 
             //reduce velocity directly
             rb.velocity -= new Vector3 (0, 0, rb.velocity.z / 3f);
         }
     }
 
 }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by $$anonymous$$ · Dec 06, 2015 at 03:23 PM

I have similar problems, but in this particular case, the whole script works fine till we use

    Mathf.Clamp (rigidbody.position.x, boundary.xMin, boundary.xMax), 
                 0.0f, 
                 Mathf.Clamp (rigidbody.position.z, boundary.zMin, boundary.zMax)
             );

and

  rigidbody.rotation = Quaternion.Euler (0.0f, 0.0f, rigidbody.velocity.x * -tilt);

Simply put the limiting of position and giving the tilt option code in current and latest Unity 5.1-2 using Visual Studios or Mondevelop code editors say these strings are in error and do not give solutions that make them work.

Ad while the link reference to the "Flow chart" on how things "should work" is all fine and dandy, on how things should "work flow" together, its not an explanation why this string of code is "No Worky" in current Unity5 and I have looked through the Scripting tutorials and do not find any examples.

Its great it works in 4.6 but even the expanded version does not work properly in the latest versions of Unity5, and incidently with the enemies, and weapon code, "No worky" right in 4.6 either..

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by dhulke · May 10, 2016 at 02:18 PM

I actually found out that the 0.2 part of the 6.2 is related to the fixed timestep. If you change the fixed timestep to 0.05 your ships limit will be 6.5. I dont exactly understand why and would apreciate if someone explained that to me.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image OneProGoober · May 19, 2016 at 04:11 AM 0
Share

Fixed update is called every .02 seconds. If you change the time then your limit will increase to the speed*the update time.. Does this make sense to you? The update occurs and then after we update the movement of the ship we check the boundary. So it could potentially be at the boundary and then after an update it could be past the boundary momentarily.

avatar image dhulke · May 19, 2016 at 04:58 AM 0
Share

Actually it doesn't make sense. When FixedUpdate is called, I first change the position of the ship (velocity), which could get past the limit, but then, after that, I clamp the position. So it doesn't matter how long a timestep takes, I'm always clamping the position after moving the ship. $$anonymous$$athf.Clamp is the last function called before Update is called and renders the ship. So that makes absolutely no sense. What does make sense is to say that regardless of the order you set the position, the velocity is always processed at the end of FixedUpdate. That would make sense.

avatar image
0

Answer by seakyihong · Sep 11, 2017 at 02:44 AM

You just need to input the numbers in xMin xMax zMin zMax in unity.

Move your player object in Scene to get the number you want

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

14 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Clamping movement range on X-axis 0 Answers

Why is the boundary not working? 1 Answer

Object gets stuck outside boundary if pushed 0 Answers

How can I make the Unity Standard Asset plane move in a scripted manner? 1 Answer

Scripting errors I don't know how to fix! Can anyone help? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges