While @dislekcia's totally right above, it sounds like we're dealing with a 2D game here, where the benefits of quaternions and their lack of susceptibility to gimbal lock is not a necessary or required property, then I don't think there's anything wrong with thinking in angles of rotation around your camera forward axis, especially not if it makes everything easier to understand. So with that, I don't see anything particular wrong with using Quaternion.Euler, and it's likely a cause for fewer errors than having to think in terms of maths you don't understand.
That aside, they really aren't that complicated, no! They are basically a point on a 4d sphere, which is a way to represent a rotation between two directions in a similar way to how a matrix can represent a transformation.
The issue you're having could be down to a number of factors, including a confusion between which vectors you should be using. Previewing these in the unity editor is useful, and remember the differences between local and world space/rotation (red is the x axis, green is y, blue is z. rgb=xyz). If you're rotating things around their forward axis, you're changing the direction their up and right axes will face. The default rotation of your sprite represents how exactly you need to get a thing to face the correct direction. I strongly recommend you have your prefabs/sprites oriented either that they point towards your up axis, or your forward axis, just for ease of use. Forward is preferable for 3D games, but it can unnecessarily complicate things in 2D, in which case you might prefer up.
I worked only in gamemaker for about a year, my first real dive into Unity was around April last year during Ludum Dare.
When should you move to Unity? When you understand gamemaker enough to know that there's something you want to do that you can't do in gamemaker.
Tools are only tools. Use whatever you like and are comfortable with. There are MANY people who make games commercially with gamemaker exclusively - there's no reason to abandon it if you don't feel that you need to.
Hey guys....... I have no knowledge of coding at all, and I have no 3d studio.... How can I make a first person shooter with unity?.......Maybe some coding tutotials?
@Mike16y check out www.cooking with unity.com they have a physics puzzler series (fps style like portal) as well as a FPS series of tutorials. All art is done in unity and he explains the code somewhat as he works through it.
Need some help with a silly problem. I have a round gameobject (2d sprite of a planet). I currently have 2 BoxCollider2Ds attached to it. One to the top half and One to the bottom half. They are set up as triggers. When the player enters the trigger's they affect the gravity of the player. The top one pulling the player down, and the other pushing the player up. I got this working the way I want...sort of...well I would prefer if I had 2 CircleCorllider2Ds..or half circles. Any ideas. Here is a pic to better explain what I want:
@Tuism thanks for the prompt response. YES!!!! I can edit the Polygon one to suit my needs. Knew I was missing some obivious solution. Just also saw effectors too. Guess that could be another solution.
I'm making a series of Unity stuff that will open each other, so call them A, B and C.
For example: Player is in A, and presses [3], it'll open C. Player is in A, and presses [2], it'll open B. Player is in A, and presses [1], it won't do anything.
I'm using this code to open stuff (in Windows). This opens a file that's in the same folder as the original game.
Process process = new Process();
process.StartInfo.FileName = Application.dataPath + "/../" + "1pgame.exe";
process.Start();
process.WaitForExit();
The question I have is - when I make A open B and make B open A again, it launches a separate instance of the game, and since the original game doesn't close, you end up with duplicate instances of games.
How do you: 1. Close the current game then launch another game, so that there won't ever be more than one thing running at a time? Or 2. How do you make it more like an alt-tab to a different game rather than open another instance of the game? (I've checked out Force Single Instance in build options, but it seems to only make any subsequent launches fail, instead of giving the old game focus and switching to it. Or 3. Any other ideas?
Richard wrote the wrapper for the AMAZE little mini arcade that ran their bunch of games, which gave me this idea. Not sure if they had this same problem though.
Thanks @Elyaradine, I tried to understand that but failed :P
I did however work out a janky solution, I start the new game and immediately quit the current one, and that way there are never old processes lying around.
Process process = new Process();
process.StartInfo.FileName = Application.dataPath + "/../" + "1pgame.exe";
process.Start();
Application.Quit()
I have a weird one, or at least I find it weird, dunno where to look...
I'm using a struct to define a PlayerObject, then passing one of the PlayerObjects into a function. In the function, I can't seem to refer to the PlayerObject and make changes to its functions, but I can refer to an instance of the PlayerObject and change it directly... What am I doing wrong?
Relevant code:
public struct PlayerObject
{
public int state;
}
public class GameController : MonoBehaviour
{
public PlayerObject P1;
etc etc
void MoveBlocks (PlayerObject _player, Vector2 _direction)
{
_player.state += 1; // this line doesn't work
P1.state += 1; //this line works
}
}
Of the two lines there in the MoveBlocks function, the first doesn't work, no errors, nothing. The second line works, but I want to pass different PlayerObjects into the function so that it's not always the same PlayerObject.
I have an object that arbitrarily moves around a spherical world, and I have a camera that orbits it by moving the mouse left and right. So far so good.
I want to get the forward vector relative to the object (whose up is always the zero point) and the ground plane (which is a 3D sphere).
I've tried Vector3.ProjectOnPlane(Vector3 vector, Vector3 planeNormal), where vector is the camera's eulerAngles and planeNormal is playerobject.transform.position - vector3.zero... But this produces weird results. Am I on the right track or is it something else completely?
Theoretically it's a 90 degree from the zero point to the player object, and then from the camera to the player, then forward along the "ground plane".
My first thought was the same as critc's, so +1 to that. But maybe that's not what you are actually after? If so maybe posting a screenshot might help, as from the 2D image it is a bit hard to fully understand your current scenario aside from the aforementioned solution.
If you need to "bend" that forward vector around the sphere, something I've done in the past (it was actually used on the Broforce world map), was to take that transform.forward vector, normalize it, and multiply that by your sphere's radius+object's height above ground. That may or may not work well depending on what you're actually trying to do. <_<
No my ship isn't pointing forward, the camera is orbiting the ship, and I want to point the ship away from the camera, but parallel to the floor - not exactly the same direction as the camera....
Let me try and show this visually...
In this image you see the setup - the sphere is interior, the ship is inside the sphere, gravity "outwards", attached to the wall of the sphere, and the camera's up is towards the centre of the sphere. So far so good.
But I can't figure out how to get a forward on the ship - I seemed to have hacked together a way for it to always face away from the ship, but I want an actual vector - and I should be able to get it from the player ship object, but it just isn't. I don't know why...
In this image you see the blue debug ray. It is this: Debug.DrawRay(PlayerObject.transform.position, PlayerObject.transform.eulerAngles*10f, Color.blue);
Where PlayerObject is that ship object. No mistake. This should make it shoot a ray forward, correct? Well it doesn't, and it even doesn't follow the ship's rotation when I turn the camera.
So what I'm looking to do is to get the ship to treat the inside of the sphere as any normal floor, and I want a forward that's "parallel" to the ship and its floor, aimed by the camera's facing towards the ship. Hopefully this makes more sense?
Okay so now that I have the ship's forward, I am realising that I need more than that :/
I want to have the ship face away from the camera, but along the "ground plane" and not the literal forward of the camera. I found ProjectOnPlane which I assume takes a 3D vector and returns a 2D vector, but it's not working, am I overlooking some angle thing again? :/
Try taking a cross product of (ground-ship) and (camera-ship) positions, it should give you the left/right vector that is parallel to the floor (I hope).
@critic Thanks, sp crossing those gets a left/right, then I need to turn it 90 degrees again to get a forward? Isn't there an easier and more direct way?
If you need to "bend" that forward vector around the sphere, something I've done in the past (it was actually used on the Broforce world map), was to take that transform.forward vector, normalize it, and multiply that by your sphere's radius+object's height above ground. That may or may not work well depending on what you're actually trying to do. <_<
@critic Thanks, sp crossing those gets a left/right, then I need to turn it 90 degrees again to get a forward? Isn't there an easier and more direct way?
You could take another cross product from (ground-ship) and that new vector, or rotate your model by 90 degrees from the beginning.
If you need to "bend" that forward vector around the sphere, something I've done in the past (it was actually used on the Broforce world map), was to take that transform.forward vector, normalize it, and multiply that by your sphere's radius+object's height above ground. That may or may not work well depending on what you're actually trying to do. <_<
Have you tried this?
I'm actually not sure what the maths here does :/ I don't think it's what I needed to do... Mostly probably because my explanation is difficult to understand XD
@critic I want to try and keep calculations down so it doesn't confuse my already-confused head :/
Somehow I've actually gotten it to work through a system of nested gameObjects, here's a summary of my system: 1. The player object's up is pulled towards and away from the zero point of the sphere, thanks to @EvanGreenwood's tech :) 2. Rotate the player left and right with Input.GetAxis("Mouse X") 3. Camera's container LookAt() at player object, up is sphere's zero.
--------------------------------
Now I have a new problem - I want the player object to hover above the "ground" without touching it, and doing it with AddForce is giving me a rubber band effect of either WAY too much force or WAY too little force. I can't actually just constrain or set a Y height because the environment is spherical.... Is there a way to take distance from centre and just pull the object towards it?
This is what I got right now that gives me mad bouncy mothion:
@Tuism I think you would want to raycast to the ground so that you know how far you are currently above ground. I guess you could use the distance from core, but what if (for example) your player jumps/walks over a cliff and now his distance from the core is not at max but he is actually not on the ground anymore. So he should be pushed, however it might all make sense in your project in how it works.
The main thing is I don't think you need the if distFromCore > 90, unless that is for some other interaction. You need to however calculate how far your space ship is from where you want it, percentage wise, decide on a force you will use to get it to where it should be and multiply that by the percentage value that it is off.
This one uses the raycast way
public float hoverHeight=1f; //Whatever is needed
public float hoverForce=1f; //Whatever is needed
Ray ray = new Ray(transform.position, -transform.up);
RaycastHit groundHit;
if (Physics.Raycast(ray, out groundHit, hoverHeight))
{
float relativeHeight = (hoverHeight - groundHit.distance) / hoverHeight;
Vector3 appliedHoverForce = Vector3.up * relativeHeight * hoverForce;
PlayerObject.AddForce(appliedHoverForce, ForceMode.Acceleration);
}
This one uses the distFromCore I just zeroed my player's x,z values to get a more accurate distFromCore since i was testing this on a flat plane, and all that matters then is the Y Value
Also I used Vector3.up for the force directions where you would want to use PlayerObject's Up vector or if that's not accurate the one you calculated vectorUp. The same for the raytrace, fire it using your vector if needs be.
You will need to set the hoverForce and height variables to what you need.
If this is still too bumpy, and you want to use AddForce, a PID should work, that way the add force will be adjusted so that the value of the force will keep it hovering at just the right height(That you set) However that is from engineering systems so won't be low on the calculations side. But here's what that looks like irl: And overall you could just get a PID class/script and plug in your values and go for it. I have a few links to some good Unity examples but you should be able to find them with a google search.
Oh I think I did a PID a while ago. Copy pasted a bunch of code and tweaked. Man I was hoping there was a simpler way than PID because everytime I engage with mad code like that I have to re-understand everything :/
Thanks for the reminder! If you have (easy to understand :P) links please let me know :)
Did you see my post before I posted the PID suggestion? Or did that not work?
Anyhoo for PID's: Take a look at the third post from Brian-Stone on this link or andeee's implementation here.
Both of them are implemented in Unity and provide either an example project or asset bundle. Brian-Stone explains in his post what a PID is quite well, and although it get's a little daunting, it is nothing compared to the wiki page on PID's linked in andeee's post. Also you don't necessarily have to understand how it all works, simply use the class, pass in you values and use the default P,I and D values given in the example. Then look at the Manual Tuning Table on the wiki page to get an idea on what value to tweak if you are overshooting etc.
One note, I believe Brian-Stone's example has a few errors in that unity changed the api from rigidbody.whatever to GetComponent<Rigidbody>().whatever so you will need to make those changes, but it will only take a few seconds.
Lastly, Brian's PID Class takes in only two arguments, and the other takes 3. The difference being in brian's you will pass in your error value only(IE I am 0.5m from where I want to be) and the other you pass in your current height and destination height.(IE I am at 1.5m I want to be at 1m) So overall both will then do the same. The one just makes the subtraction inside the method the other you calculate it yourself.
@vince yeah I tried your code and plugged in my values... And I'm not sure if I was messing things up but it didn't work at all, the object fell to the sphere wall like a stone, or it would drift. I tweaked the values a bunch and couldn't get it to cooperate.
I actually ended up looking at the same PID class you linked, I'm not sure how exactly to implement yet given my variables are a bit more complex, (mostly given I don't actually have a target object, just a target value, and up/down is not a consistent axis but towards/away from the centre) but I'll give it another shot :)
Ah okay. I tested it on a flat plane so maybe it doesn't/won't work in a spherical environment.
To use the PID, it does not really care or know what it is doing, it just takes two(or one) float and spits out the return value.
So you would calculate your current height from the floor every frame, and pass the PID that and the height that you want to be above the floor (Which I am assuming will stay constant). So lets say for this frame you calculated your current height is 0.8f and your target is 1f, you pass those and your PID will return a float, the size of which will depend on your P,I and D values. You then use the returned value as your AddForce amount.
To actually make the PID work you need to set the P,I and D values correctly, this usually works quite well for me (From the PID Wiki linked above):
One tuning method is to first set Ki and Kd values to zero.
Increase the Kp until the output of the loop oscillates, then the Kp should be set to approximately half of that value for a "quarter amplitude decay"(Read: Settles quickly) type response.
Then increase Ki until any offset is corrected in sufficient time for the process. However, too much Ki will cause instability.
Finally, increase Kd, if required, until the loop is acceptably quick to reach its reference after a load disturbance. However, too much Kd will cause excessive response and overshoot.
Also as stated above, sometimes a Kd of zero works perfectly fine, and I often use them like this. The Table in that link is also very useful for adjusting your values to work.
Thanks so much! So I tried the class and I've been wondering what the error was in there that you said need editing? And I noticed that if I set the D value to anything but 0 it would completely bug out... So... Dunno?
It was a few syntax errors, so it will give you the lines where the errors are. (This is in Brian's class implementation, not the PID class itself if i recall correctly) So it was small things like changing rigidbody to the new GetComponent<Rigidbody>() etc.
I'd be more than happy to try take a look at it all in your scene if you could/are allowed to share it, as I'd like to take a look at how you are doing the spherical world, since I've always wondered.
@vince file attached! It's my pleasure to share this hack :P I've got the example scene in there and I'm not sure if the script can be implemented in my code with just substituting what's in the editor... I think.
Hey. Played around with both the first suggestion and the PID, heres the file
Hopefully that gives you something to work with. One problem is accelerating forward seems to add additional downward force to the player object, causing it to dive, and the PID can't respond quick enough. But it is indeed working. Let me know if you have any problems.
P.S. I implemented it all in the CustomGravity script as my Visual Studio was downloading other packages, and mono was giving trouble, and didn't pick up the other files in the solution, so had no reference to the PID Class; and so I just copied the PID class over in to there and renamed it. You'll know when you see it. Just know I did everything in CustomGravity since all my tools were broken :/
I have a set a Vector3 points-of-interest for a model in model space (i.e. if the model's origin was at (0,0,0)) and when I do a raycast and hit the model, I want to know which of the points-of-interest is closest to the collision point.
My current plan is to iterate through each point and apply the models translation and rotation to the point of interest before checking the distance to the collision point (because the collision point is in world space); but I don't know how to apply the translation and rotation to a single point.
As far as I know, if you just subtract the two positions you get a distance, if there's not too many of them you can just iterate through them all and get the one with the shortest distance.
EDIT: On closer reading, what I would do is get the collision point in worldspace, then iterate through the point of interests and get their localspace positions and change them to worldspace (transform.TransformPoint) (https://docs.unity3d.com/ScriptReference/Transform.TransformPoint.html) and do the distance calc from there.
@Fengol If the POI are simply relative to model local, then their position vectors (x,y,z) are relative to (0,0,0). You can add the transform.position vector of the model to the POI vector to change the POI position vector to world space. So as you loop through the set, you can add the model transform.position and then do the distance calculation.
I don't know if this is the best way, but it should work.
Further thinking, you could just take the raycasthit.point vector (from the collision) subtract the models transform.position vector and you will be left with a local space vector to the model, which can use to do the distance calculations to the POIs.
@Thelangfordian, I need to include the rotation as well as the position. If the model is facing backwards the POI are on opposite sides. But how do I apply rotation to a point?
And it does work in terms of stabilising the rotation,, but it also seems to have a weird other effect in that it seems to apply a force to the forward vector too, other than the strictly up and down (in relation to the ship) vectors that I was expecting. (I know this because I have a thing where I turn the drag off and the ship is able to rotate freely while it's still moving in a direction due to momentum. When this "rotation stabilsation" is in effect, the ship also changes movement vector, which it shouldn't.
Any particular reason you are using separate Rigidbodies to apply Forces to and not using the AddTorque function on the main ship rigidbody? Rigidbody.AddTorque
@Thelangfordian... I think I set it up like that because the body itself shifted all around and I wasn't sure if I could figure out a local rotation relative to the heading of the ship instead of the global torque.
But anyway does it matter? Would changing it to local torque make it easier to do a stabilisation force? If so how?
Essentially, when using the force as thrusters, you can have additional directional forces (over the rotational forces) on the main body, and you would need correcting directional forces to oppose these. You can see this in some of the videos where astronauts use thrusters to move around, to stop rotating there is a rotational thruster as well as a directional thruster that will fire.
In Unity when using Inertia, you are getting pure rotation force, which reduces some of the physics complexity.
Anyway. I have attached a unitypackage where I set up a quick 2D example. Load the scene... L key - left thruster R key - right thruster I key - clockwise inertia force O key - counter-clockwise inertia force
So, if you are only intending on rotating the ship for a barrel roll, then I think adding torque around the forward vector of the ship is probably the simplest solution.
Comments
That aside, they really aren't that complicated, no! They are basically a point on a 4d sphere, which is a way to represent a rotation between two directions in a similar way to how a matrix can represent a transformation.
The issue you're having could be down to a number of factors, including a confusion between which vectors you should be using. Previewing these in the unity editor is useful, and remember the differences between local and world space/rotation (red is the x axis, green is y, blue is z. rgb=xyz). If you're rotating things around their forward axis, you're changing the direction their up and right axes will face. The default rotation of your sprite represents how exactly you need to get a thing to face the correct direction. I strongly recommend you have your prefabs/sprites oriented either that they point towards your up axis, or your forward axis, just for ease of use. Forward is preferable for 3D games, but it can unnecessarily complicate things in 2D, in which case you might prefer up.
Ive been using gamemaker for a while and i want to know when must i use unity because still dont understand whats going on in unity
When should you move to Unity?
When you understand gamemaker enough to know that there's something you want to do that you can't do in gamemaker.
Tools are only tools. Use whatever you like and are comfortable with. There are MANY people who make games commercially with gamemaker exclusively - there's no reason to abandon it if you don't feel that you need to.
Need some help with a silly problem. I have a round gameobject (2d sprite of a planet). I currently have 2 BoxCollider2Ds attached to it. One to the top half and One to the bottom half. They are set up as triggers. When the player enters the trigger's they affect the gravity of the player. The top one pulling the player down, and the other pushing the player up. I got this working the way I want...sort of...well I would prefer if I had 2 CircleCorllider2Ds..or half circles. Any ideas. Here is a pic to better explain what I want:
http://docs.unity3d.com/ScriptReference/PolygonCollider2D.html
Do you actually need them to be circular? Would the two boxes not be good enough?
I don't think there are half circles in colliderland.
Alternatively, you can detect distance from the centre to any object, then decide if it's above or below simply enough with just the y co-cordinate.
I'm making a series of Unity stuff that will open each other, so call them A, B and C.
For example:
Player is in A, and presses [3], it'll open C.
Player is in A, and presses [2], it'll open B.
Player is in A, and presses [1], it won't do anything.
I'm using this code to open stuff (in Windows). This opens a file that's in the same folder as the original game.
The question I have is - when I make A open B and make B open A again, it launches a separate instance of the game, and since the original game doesn't close, you end up with duplicate instances of games.
How do you:
1. Close the current game then launch another game, so that there won't ever be more than one thing running at a time? Or
2. How do you make it more like an alt-tab to a different game rather than open another instance of the game? (I've checked out Force Single Instance in build options, but it seems to only make any subsequent launches fail, instead of giving the old game focus and switching to it. Or
3. Any other ideas?
Richard wrote the wrapper for the AMAZE little mini arcade that ran their bunch of games, which gave me this idea. Not sure if they had this same problem though.
http://stackoverflow.com/questions/7357675/how-can-i-set-the-focus-to-application-which-is-allready-in-running-state
I did however work out a janky solution, I start the new game and immediately quit the current one, and that way there are never old processes lying around.
Seems to work :D
I have a weird one, or at least I find it weird, dunno where to look...
I'm using a struct to define a PlayerObject, then passing one of the PlayerObjects into a function. In the function, I can't seem to refer to the PlayerObject and make changes to its functions, but I can refer to an instance of the PlayerObject and change it directly... What am I doing wrong?
Relevant code:
Of the two lines there in the MoveBlocks function, the first doesn't work, no errors, nothing. The second line works, but I want to pass different PlayerObjects into the function so that it's not always the same PlayerObject.
What am I missing?
The way to solve it is to change the struct to a class.
Is there any reason to use this rather than changing the struct to a class?
https://msdn.microsoft.com/en-us/library/ms229017(v=vs.110).aspx?f=255&MSPPError=-2147217396
I have an object that arbitrarily moves around a spherical world, and I have a camera that orbits it by moving the mouse left and right. So far so good.
I want to get the forward vector relative to the object (whose up is always the zero point) and the ground plane (which is a 3D sphere).
I've tried Vector3.ProjectOnPlane(Vector3 vector, Vector3 planeNormal), where vector is the camera's eulerAngles and planeNormal is playerobject.transform.position - vector3.zero... But this produces weird results. Am I on the right track or is it something else completely?
Theoretically it's a 90 degree from the zero point to the player object, and then from the camera to the player, then forward along the "ground plane".
Thanks for assisting!
(I'm looking for the red vector)
Let me try and show this visually...
In this image you see the setup - the sphere is interior, the ship is inside the sphere, gravity "outwards", attached to the wall of the sphere, and the camera's up is towards the centre of the sphere. So far so good.
But I can't figure out how to get a forward on the ship - I seemed to have hacked together a way for it to always face away from the ship, but I want an actual vector - and I should be able to get it from the player ship object, but it just isn't. I don't know why...
In this image you see the blue debug ray. It is this:
Debug.DrawRay(PlayerObject.transform.position, PlayerObject.transform.eulerAngles*10f, Color.blue);
Where PlayerObject is that ship object. No mistake. This should make it shoot a ray forward, correct? Well it doesn't, and it even doesn't follow the ship's rotation when I turn the camera.
So what I'm looking to do is to get the ship to treat the inside of the sphere as any normal floor, and I want a forward that's "parallel" to the ship and its floor, aimed by the camera's facing towards the ship. Hopefully this makes more sense?
Thanks again for looking!!!
doesn't do what you think it does. The direction should be given as a direction in world space, not in terms of Euler angles.
gives you a vector pointing in the direction the transform is facing (whatever it is you do with it; I'm a bit too tired to think through that).
Okay so now that I have the ship's forward, I am realising that I need more than that :/
I want to have the ship face away from the camera, but along the "ground plane" and not the literal forward of the camera. I found ProjectOnPlane which I assume takes a 3D vector and returns a 2D vector, but it's not working, am I overlooking some angle thing again? :/
PlayerObject.transform.eulerAngles = Vector3.ProjectOnPlane(Camera.main.transform.forward, (Vector3.zero - PlayerObject.transform.position));
Where Vector3.zero is the centre of the sphere...
Thanks again guysssss
@critic I want to try and keep calculations down so it doesn't confuse my already-confused head :/
Somehow I've actually gotten it to work through a system of nested gameObjects, here's a summary of my system:
1. The player object's up is pulled towards and away from the zero point of the sphere, thanks to @EvanGreenwood's tech :)
2. Rotate the player left and right with Input.GetAxis("Mouse X")
3. Camera's container LookAt() at player object, up is sphere's zero.
--------------------------------
Now I have a new problem - I want the player object to hover above the "ground" without touching it, and doing it with AddForce is giving me a rubber band effect of either WAY too much force or WAY too little force. I can't actually just constrain or set a Y height because the environment is spherical.... Is there a way to take distance from centre and just pull the object towards it?
This is what I got right now that gives me mad bouncy mothion:
The main thing is I don't think you need the if distFromCore > 90, unless that is for some other interaction. You need to however calculate how far your space ship is from where you want it, percentage wise, decide on a force you will use to get it to where it should be and multiply that by the percentage value that it is off.
This one uses the raycast way
This one uses the distFromCore
I just zeroed my player's x,z values to get a more accurate distFromCore since i was testing this on a flat plane, and all that matters then is the Y Value
Also I used Vector3.up for the force directions where you would want to use PlayerObject's Up vector or if that's not accurate the one you calculated vectorUp. The same for the raytrace, fire it using your vector if needs be.
You will need to set the hoverForce and height variables to what you need.
And overall you could just get a PID class/script and plug in your values and go for it. I have a few links to some good Unity examples but you should be able to find them with a google search.
Thanks for the reminder! If you have (easy to understand :P) links please let me know :)
Anyhoo for PID's:
Take a look at the third post from Brian-Stone on this link or andeee's implementation here.
Both of them are implemented in Unity and provide either an example project or asset bundle. Brian-Stone explains in his post what a PID is quite well, and although it get's a little daunting, it is nothing compared to the wiki page on PID's linked in andeee's post. Also you don't necessarily have to understand how it all works, simply use the class, pass in you values and use the default P,I and D values given in the example. Then look at the Manual Tuning Table on the wiki page to get an idea on what value to tweak if you are overshooting etc.
One note, I believe Brian-Stone's example has a few errors in that unity changed the api from rigidbody.whatever to GetComponent<Rigidbody>().whatever so you will need to make those changes, but it will only take a few seconds.
Lastly, Brian's PID Class takes in only two arguments, and the other takes 3. The difference being in brian's you will pass in your error value only(IE I am 0.5m from where I want to be) and the other you pass in your current height and destination height.(IE I am at 1.5m I want to be at 1m) So overall both will then do the same. The one just makes the subtraction inside the method the other you calculate it yourself.
I actually ended up looking at the same PID class you linked, I'm not sure how exactly to implement yet given my variables are a bit more complex, (mostly given I don't actually have a target object, just a target value, and up/down is not a consistent axis but towards/away from the centre) but I'll give it another shot :)
To use the PID, it does not really care or know what it is doing, it just takes two(or one) float and spits out the return value.
So you would calculate your current height from the floor every frame, and pass the PID that and the height that you want to be above the floor (Which I am assuming will stay constant). So lets say for this frame you calculated your current height is 0.8f and your target is 1f, you pass those and your PID will return a float, the size of which will depend on your P,I and D values. You then use the returned value as your AddForce amount.
To actually make the PID work you need to set the P,I and D values correctly, this usually works quite well for me (From the PID Wiki linked above): Also as stated above, sometimes a Kd of zero works perfectly fine, and I often use them like this. The Table in that link is also very useful for adjusting your values to work.
I'd be more than happy to try take a look at it all in your scene if you could/are allowed to share it, as I'd like to take a look at how you are doing the spherical world, since I've always wondered.
Hopefully that gives you something to work with. One problem is accelerating forward seems to add additional downward force to the player object, causing it to dive, and the PID can't respond quick enough. But it is indeed working. Let me know if you have any problems.
P.S. I implemented it all in the CustomGravity script as my Visual Studio was downloading other packages, and mono was giving trouble, and didn't pick up the other files in the solution, so had no reference to the PID Class; and so I just copied the PID class over in to there and renamed it. You'll know when you see it. Just know I did everything in CustomGravity since all my tools were broken :/
Here's the code:
Public Settings:
PFactor : 10
IFactor : 0.9
DFactor: 6
Hover Force: 300
HoverHeight: Whatever you need, around 5 seems good
I have a set a Vector3 points-of-interest for a model in model space (i.e. if the model's origin was at (0,0,0)) and when I do a raycast and hit the model, I want to know which of the points-of-interest is closest to the collision point.
My current plan is to iterate through each point and apply the models translation and rotation to the point of interest before checking the distance to the collision point (because the collision point is in world space); but I don't know how to apply the translation and rotation to a single point.
Any suggestions?
EDIT: On closer reading, what I would do is get the collision point in worldspace, then iterate through the point of interests and get their localspace positions and change them to worldspace (transform.TransformPoint) (https://docs.unity3d.com/ScriptReference/Transform.TransformPoint.html) and do the distance calc from there.
If the POI are simply relative to model local, then their position vectors (x,y,z) are relative to (0,0,0).
You can add the transform.position vector of the model to the POI vector to change the POI position vector to world space.
So as you loop through the set, you can add the model transform.position and then do the distance calculation.
I don't know if this is the best way, but it should work.
Further thinking, you could just take the raycasthit.point vector (from the collision) subtract the models transform.position vector and you will be left with a local space vector to the model, which can use to do the distance calculations to the POIs.
[Update] - Thanks @Tuism, that's exactly what I was looking for!
I've got a "ship" setup which spins (barrel-rolls) by applying a force up and down on two rigidbodies on the left and right side of the ship.
(front view of the ship, with the two rigidbodies that I apply forces to to barrel roll the whole thing)
I want to then get a "stabilisation" thing going when the ship is supposed to fly straight. So I want a way to "cancel out" the spinning force.
I've figured this out:
And it does work in terms of stabilising the rotation,, but it also seems to have a weird other effect in that it seems to apply a force to the forward vector too, other than the strictly up and down (in relation to the ship) vectors that I was expecting. (I know this because I have a thing where I turn the drag off and the ship is able to rotate freely while it's still moving in a direction due to momentum. When this "rotation stabilsation" is in effect, the ship also changes movement vector, which it shouldn't.
What am I missing here?
Thanks in advance guys :)
Any particular reason you are using separate Rigidbodies to apply Forces to and not using the AddTorque function on the main ship rigidbody?
Rigidbody.AddTorque
But anyway does it matter? Would changing it to local torque make it easier to do a stabilisation force? If so how?
Essentially, when using the force as thrusters, you can have additional directional forces (over the rotational forces) on the main body, and you would need correcting directional forces to oppose these. You can see this in some of the videos where astronauts use thrusters to move around, to stop rotating there is a rotational thruster as well as a directional thruster that will fire.
In Unity when using Inertia, you are getting pure rotation force, which reduces some of the physics complexity.
Anyway. I have attached a unitypackage where I set up a quick 2D example.
Load the scene...
L key - left thruster
R key - right thruster
I key - clockwise inertia force
O key - counter-clockwise inertia force
Edit: Oh and put Gizmos on in your scene view.
I hope it's useful.
So, if you are only intending on rotating the ship for a barrel roll, then I think adding torque around the forward vector of the ship is probably the simplest solution.
Something like