- Home /
forward movement in camera direction (not direction of rigid body only)
Hi,
before starting It's important that we all know im noobish. Started using unity a few weeks ago for a project on my IMDesign degree and have little coding knowledge.
Ok so my problem is with SWIMMING in my water section. I have a rock type shore with a cave section under the water level. I would like for the user to be able to swim through the cave system as opposed to walking through it.
I am using the standard first person controller
After reading around these answers, videos etc, I am at the stage where I have:
Zero gravity under water by way of a box collider with the script found here attached.
This means that I float on the surface which is great. But I am unable to dive/swim down into the water!
this link allowed me to get as far as I have. I am stumped trying to code forwards movement in the absolute direction of camera
I thought the simplest way would be to grab the underwaterLevel position from this script
//This script enables underwater effects. Attach to main camera.
//Define variables var underwaterLevel = 7;
//The scene's default fog settings private var defaultFog = RenderSettings.fog; private var defaultFogColor = RenderSettings.fogColor; private var defaultFogDensity = RenderSettings.fogDensity; private var defaultSkybox = RenderSettings.skybox; var noSkybox : Material;
function Start () { //Set the background color camera.backgroundColor = Color (0, 0.4, 0.7, 1); }
function Update () { if (transform.position.y < underwaterLevel) { RenderSettings.fog = true; RenderSettings.fogColor = Color (0, 0, 0, 0); RenderSettings.fogDensity = 0.02; RenderSettings.skybox = noSkybox;
}
else {
RenderSettings.fog = defaultFog;
RenderSettings.fogColor = defaultFogColor;
RenderSettings.fogDensity = defaultFogDensity;
RenderSettings.skybox = defaultSkybox;
}
}
to determine when to switch the movement type? or grab something from the box collider that switches gravity off? Even still, I can't find the exact part of FPS motor script to modify..
Any help would be greatly appreciated as I'm totally confused :|
Sorry for the ramblings - i tend to do that.
Much thanks for reading,
Oli
Answer by Taugeshtu · Apr 15, 2011 at 03:20 PM
My suggestion is:
Make your own tiny script.
- Let it care about detection for underwater (if you hasn't changing gravity and water level is constant along the scene, then just one float variable and transform.position.y is enough for detection, if not - BoxCollider triggers are for you).
- Let it disable all movement control scripts on prefab (use gameObject.GetComponent() for that), but don't disable mouselook!
- Take Input data yourself in tiny script and simply convert it. There are few code to help you orient in what you need (this is not actually working code, you should write it yourself in any way you like to do it):
var moveDirection = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")); moveDirection = Camera.main.transform.TransformDirection(moveDirection);
var controller : CharacterController = GetComponent(CharacterController); controller.Move(moveDirection * Time.deltaTime);
Hey, thanks for the reply. There is water on different leves so that's why I went for the box collider. I'm thinking I like what you suggest as I understand what you are saying and you've included the forward movement in direction of camera like The Stone says. However when I try to find and disable the scripts attached to FPS controller from my box collider, I get no errors, but the scripts are still active! I'm using the var go GameObject.Find with getComponent. Any ideas? I'm in the process of working with a script attached to FPS controller right now incase.. THanks, Oli
Why GameObject.Find? Just gameObject.GetComponent(some_controller_script) Then, make a var for component you're trying to disable and watch it in Inspector view (Debug mode should helps too), use Debug.Log(); to throw messages in console after different ifs and other debug stuff - I won't believe that one script couldn't disable another ;)
Answer by TowerOfBricks · Apr 15, 2011 at 02:42 PM
The forward direction of a transform can be found by
var theForwardDirection = transform.TransformDirection (Vector3.forward);
So finding the forward direction of the main camera isn't hard
var theForwardDirection = Camera.main.transform.TransformDirection (Vector3.forward);
Then of-course this direction will usually be a bit tilted downwards or upwards so you might want to zero that
theForwardDirection.y = 0;
And perhaps normalize it to get a constant speed if you are using it for that.
theForwardDirection.Normalize ();
[Edit] The code in FPSInputController which should be changed:
//Previous code //var directionVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
//New code //Forward direction also has a shortcut, transform.forward var directionVector = Camera.main.transform.forward; //No downward movement directionVector.y = 0; //Scale it by how fast the user wants to move directionVector *= Input.GetAxis("Vertical");
Hi, thanks for the response, I understand how you've deter$$anonymous$$ed the forward direction of the camera, but I am unable to actually move in that direction. I've tried disabling fixed rotation in the mouse look script but the body of the character still does not rotate. the closest I got was by having the vector constantly moving in direction of the camera but that's basically no forward input from the user.. could you elaborate on your answer a little? which script should I be looking to modify, or should I be making a script from scratch as Taugeshtu said and working this in? Thanks
What scripts are you using now. Try to find the line which actually moves your character right now. If you are using a rigidbody it should be something like : rigidbody.AddForce (someVariableHere). You would want to modify the "someVariableHere" variable.
Hey, I'm using the standard First person controller Prefab. $$anonymous$$ust be in cgharacter motor, but that script is complex and I can't pinpoint it. At start there is
// The current global direction we want the character to move in. var input$$anonymous$$oveDirection : Vector3 = Vector3.zero;
So that's gotta be direction. As for force I'm unsure is it the section starting with..
// Project a direction onto elliptical quater segments based on forward, sideways, and backwards speed. // The function returns the length of the resulting vector.
No, it seems you should be looking in the FPSInputController script. I have commented out the line which is currently in the script and added a few which should get you the behavior you want. //var directionVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); var directionVector = Camera.main.transform.forward; directionVector.y = 0; directionVector *= Input.GetAxis("Vertical"); I assume you want to scale it by the forward movement keys (up/down & w/s is default).
The code in my last comment looked awful without formatting, look in the answer post for the formatted code.
Answer by efge · Apr 15, 2011 at 03:06 PM
If you are in dive/swim mode you could try to disable the first person controller and/or switch off physics for your character (isKinematic = true) and manipulate transform.position and transform.rotation.
Here is another useful link: Allowing player to swim or dive in water
It will not work with standart FPS prefab in 3.0, because it's based on CharacterController, not rigidbody. I prefer to make rigidbody-based prefab on my own.
But! Here's the thing: Basically all FPS prefab scripts do - calculate (in complex and boring way) where you should be moved, and then apply this movement.
Hi efge, thanks for the link. His system is rather complex and I don't think I'll attempt something like that as I am still very new to this! There are still similarities with the box collider deter$$anonymous$$ing when submerged though. I tried what you suggested with attaching a rigid body to the player, but this reaked havoc with the physics. From that link am I right in thinking that it may be easier to make a key for swwi$$anonymous$$g up and down on the y axis as opposed to moving forwards in the direction of camera? Thanks Oli
Taugeshtu, would it be simpler to make an entire prefab from scratch then? That seems a little advanced.. Oli
Your answer
![](https://koobas.hobune.stream/wayback/20220613122950im_/https://answers.unity.com/themes/thub/images/avi.jpg)