- Home /
Add force help needed
hey guys i really need help. i am trying to make swimable underwater, but i am really stuck. i am missing something in my code. my character is the _pc object my water plane is _water the are no errors how ever this does not work at all not even the debug. any suggestions would be great...
using UnityEngine;
using System.Collections;
public class gravity : MonoBehaviour {
public GameObject _pc;
public GameObject _water;
void Start() {
_water.collider.isTrigger = true;
}
void OnTriggerEnter(Collider _water) {
if (_pc.rigidbody == true)
// Debug.Log ("we are in the water");
_pc.rigidbody.useGravity = false;
}
void OnTriggerExit(Collider _water) {
if (_pc.rigidbody)
Debug.Log ("we are out of the water");
_pc.rigidbody.useGravity = true;
}
void FixedUpdate() {
if(_water.collider.isTrigger == true){
_pc.rigidbody.AddForce(0, 50, 0);
}
}
}
for some reason it didnt space when i aske the question using UnityEngine; using System.Collections;
public class gravity : $$anonymous$$onoBehaviour { public GameObject _pc; public GameObject _water; void Start() {
_water.collider.isTrigger = true; } void OnTriggerEnter(Collider _water) { if (_pc.rigidbody == true) // Debug.Log ("we are in the water"); _pc.rigidbody.useGravity = false; } void OnTriggerExit(Collider _water) { if (_pc.rigidbody) Debug.Log ("we are out of the water"); _pc.rigidbody.useGravity = true; } void FixedUpdate() { if(_water.collider.isTrigger == true){ _pc.rigidbody.AddForce(0, 50, 0); } } }
Your question was stuck in the moderation queue because you need at least 15 karma to directly post on this site. This is to prevent spammers from flooding this site with ads. Each new post has to be verified by a user with at least 1000 karma. This might take a while depending on how many 1000+ users are online and if they view the moderation queue frequently.
Please edit your question and repost your script. You just have to select all your code and press the "101 010" button to format it right. Since the last update UnityAnswers html-escape all posts except code sections. This makes reformatting almost impossible, so please copy the code from your original source and replace it in your question.
@aldonaletto: Sure, using just the pre-tags show it correctly in a fixed font, but it's not really "marked as code". $$anonymous$$aybe some day we get syntax highlighing again but pre-sections wouldn't be "code" then.
Finally we got the question mark at the right side of the toolbar back. It shows some basic markdown rules and provides another link to the full description
@Bunny83, thanks for the hint. I saw the $$anonymous$$arkdown instructions a lot of time ago (when I joined UA, I guess), but missed them and learned the basics myself by trial-and-error (to be honest, I completely forgot that UA had adopted $$anonymous$$arkdown)
Answer by aldonaletto · Sep 15, 2012 at 02:14 AM
You're using the trigger events wrong. This script must be attached either to the water or to the player. If your script is attached to the water (trigger), you must check if the other object is the player before controlling it. If the script is attached to the player, on the other hand, you must check if the other object is the water. Supposing the script is attached to the water, it should be something like this:
using UnityEngine;
using System.Collections;
public class gravity : MonoBehaviour {
public GameObject _pc;
public GameObject _water;
bool inWater = false;
void OnTriggerEnter(Collider other) {
if (other.gameObject == _pc){ // if other object is _pc...
Debug.Log ("pc entered the water");
inWater = true; // set inWater flag
_pc.rigidbody.useGravity = false; // turn gravity off
}
}
void OnTriggerExit(Collider other) {
if (other.gameObject == _pc) // if _pc exited the trigger...
Debug.Log ("pc exited the water");
inWater = false; // set inWater to false
_pc.rigidbody.useGravity = true; // turn gravity on
}
void FixedUpdate() {
if (inWater){ // if inside water...
_pc.rigidbody.AddForce(0, 50, 0); // add force up
}
}
}
But notice that you're actually creating a "negative weight" when the player enters the water: this force up will push the player out of the water, what will turn gravity on, making it fall to the water, which in turn will activate the force up again, and so on - in other words, the player will shake up and down frenetically while over the water.
EDITED: As I said in my comment, you can try to solve the problem above applying a force proportional to the submersed height. You must also use a slightly different method to detect when the player enters and exits the water, since a mesh collider will report trigger events when the player gets completely submersed. The whole thing could be like this (water script):
using UnityEngine;
using System.Collections;
public class gravity : MonoBehaviour {
public GameObject _pc;
bool inWater = false;
float height;
float waterY;
void Start(){
waterY = transform.position.y;
}
void OnTriggerEnter(Collider other) {
float y = other.transform.position.y;
// if other is _pc and it's above the water...
if (other.gameObject == _pc && y > waterY){
inWater = true; // set inWater flag
height = 2 * (y - waterY); // estimate the player height
}
}
void OnTriggerExit(Collider other) {
float y = other.transform.position.y;
if (other.gameObject == _pc && y > waterY) // if _pc exited the trigger...
inWater = false; // set inWater to false
}
void FixedUpdate() {
if (inWater){ // if inside water...
// calculate the submersed portion (1 means 100%)
float submersion = 0.5f + (waterY - _pc.transform.position.y)/height;
submersion = Mathf.Clamp(submersion, 0, 1); // clamp to 0..1 range
// force up will be limited to ~ 80% weight when totally submersed
_pc.rigidbody.AddForce(0, _pc.rigidbody.mass * 8.0 * submersion, 0);
}
}
}
There are some mysterious tricks here. First: when the player touches the water plane, its height is estimated as twice the vertical distance between its position (the pivot) and the water plane. Second: in FixedUpdate, a submersion factor is calculated, which ranges from 0 (player has only wet his feet) to 1 (completely submersed) and multiplied by 8 to give an up force that ranges from 0 to 80% of his weight (8/9.8, the default gravity).
what what you suggest then to make this not happen, i really appreciate the support, coding is not my strong suite lol.
I would apply an up force proportional to the submersed height, without turning gravity off - this would work like a gravity reduction applied to the player only. There's another problem: if you're using the water plane and added a mesh collider to it, you must change the inWater state only when the player Y coordinate is above the water. I'll modify my answer to include this stuff.
$$anonymous$$ate you are a dead set legend,aldonaletto.