- Home /
How having correct bounce on a rotating pinwheel(it's more complicated)?
This is the rotating pinwheel on which the player must jump. The blue ray is the direction of the moving player:
This is the instant of collision:
the result is a force coming in the center. There is no reason for this force, but it's sure the player can't be separeted from the wall without touching the following wall(the below one in the second image). So the only one solution I have found has been making ball bouncing on touch with the coming wall, irrespective of the impact force. But it makes different problems:
When the player touches the wall, unity perceives the collision just after a little time from the impact. The result is a different position of the player in the moment of recording the position, so the bouncing recorded values are not correct.
To fix it I decided to record the position of the player just before the impact, having possibility to calculate the inDirection coordinates to pass as arguments in Vector3.Reflect. It works corretly when the player jumps on the pinwheel but, if it triggers with the wall coming against it when moving around the pinwheel, it gets affected by the same impossibility to deteach itself from the wall. This is because the record of the player position is placed behind the coming wall, creating a force directed against that wall. This explains the if constructor within the else inside the OnTriggerEnter method in the second script below: I divert the force.
public class PlayerPositionPrinter : MonoBehaviour { //there are more then one pinwheel. A script reference is needed
GameObject player, playerPositionPrint;
Collider colliderPrint;
PlayerRepulse playerRepulse;
public float printingTime;
bool changeDirection;
void Awake(){
playerPositionPrint = new GameObject (); //this is a reference object and a photo of the player position
playerPositionPrint.name = "Repulse Reference";
colliderPrint = playerPositionPrint.AddComponent("SphereCollider") as SphereCollider;
colliderPrint.isTrigger = true; //if the walls collides with the playerPositionPrint before then player, it is moving around the pinwheel
changeDirection = false; //and the force must be diverted: playerPoisitonPrint is placed behind the wall, the player in front of
}
void OnTriggerEnter(Collider other){ //the penwheel is placed inside a box colider that delimitates the zone. Don't consider it.
if (other.tag == "Player") {
player = other.gameObject;
StartCoroutine(PrintPlayer());
}
}
IEnumerator PrintPlayer(){
for(;;) {
playerPositionPrint.transform.position = player.transform.position; //instant print
changeDirection = false;
yield return new WaitForSeconds (printingTime); //set to 0.3
}
}
public bool GetChangeDirection(){
return(changeDirection); //changeDirection must be set to false, cause of I want the collision player would have got a single instant before
}
public Vector3 GetPlayerPositionPrint(){
return(playerPositionPrint.transform.position); //needed to define the direction
} }
public class PlayerRepulse : MonoBehaviour {
public GameObject player;
bool changeDirection;
public PlayerPositionPrinter playerPositionPrinter;
public float repulse;
void Update(){
Debug.DrawRay (player.transform.position, player.rigidbody.velocity, Color.blue);
changeDirection = playerPositionPrinter.GetChangeDirection (); //changeDirection update
}
void OnCollisionEnter(Collision collision){
if (collision.gameObject.name == "Repulse Reference") //if it's the player position print
changeDirection = true;
else
if (!changeDirection) { //first touch with the player
//Debug.DrawRay (collision.contacts [0].point, Vector3.Reflect (collision.contacts [0].point - playerPositionPrinter.GetPlayerPositionPrint (), collision.contacts [0].normal), Color.red);
player.rigidbody.velocity = Vector3.Reflect (collision.contacts [0].point - playerPositionPrinter.GetPlayerPositionPrint (), collision.contacts [0].normal) * repulse;
} else {//first touch with the Repulse Reference
Debug.DrawRay (collision.contacts [0].point, Vector3.Reflect (playerPositionPrinter.GetPlayerPositionPrint () - player.transform.position, collision.contacts [0].normal), Color.red);
player.rigidbody.velocity = Vector3.Reflect (playerPositionPrinter.GetPlayerPositionPrint () - player.transform.position, collision.contacts [0].normal) * repulse;
}
}
}
PlayerPositionPrint is attached to a reference object; PlayerRepulse to the 4 walls(at start I tried to add a force straight transform.forward: too hard to control).
Sometimes it works, sometimes not. It gets 4 effects:
The force is too feeble or too powerful for each impact, and the player could be thrown outside the pinwheel or remained attached to the wall;
this behaviour is not prevedible and the player can't be attached to wall when it wants;
this section is too hard to overtake
these instructions are too wavy if multiplied for all the pinwheels.
I am loosing too much time and I will have an exam in a month. I am asking for suggestions, solutions about how to solve this problem, any change I could do for making it more controllable. I am sorry for my English, the question too long and too general(a disaster): generally I continue trying until I don't solve the problem.