- Home /
How to optimize boat rotation
Unity's profiler has identified that the majority of my cpu is being used by this script, particularly the transform.rotatearound part, i'm experiencing rather low FPS ~40 (on a machine that can run BF3 on ultra) and was wonder how i could go about optimizing it.
(profiler says nearly 80% of the cpu used for the game is for this script alone
using UnityEngine;
using System.Collections;
public class boat : MonoBehaviour {
public float speed;
private float turnspeed=0f;
public GameObject player;
public GameObject position;
public Rigidbody boatr;
private bool onBoat=false;
private bool forward=false;
private bool left=false;
private bool right=false;
private Vector3 lastpos;
private float rotinit;
void Start () {
transform.position=new Vector3(transform.position.x,9.6f,transform.position.z);
lastpos=transform.position;
rotinit=transform.rotation.x;
}
void Update () {
//keep the boat at water level
transform.position=new Vector3(transform.position.x,9.6f,transform.position.z);
//get distance between boat and player
float distance=Vector3.Distance(player.transform.position,transform.position);
if(Input.GetKeyDown(KeyCode.T)==true){
onBoat=!onBoat;
}
if(onBoat==true){
//make player position be at the driver position on boat
player.transform.position=position.transform.position;
}
if(onBoat==true & Input.GetKeyDown(KeyCode.I)==true){
forward=true;
}
if(onBoat==true & Input.GetKeyUp(KeyCode.I)==true){
forward=false;
}
if(onBoat==true & Input.GetKeyDown(KeyCode.J)==true){
left=true;
}
if(onBoat==true & Input.GetKeyUp(KeyCode.J)==true){
left=false;
}
if(onBoat==true & Input.GetKeyDown(KeyCode.L)==true){
right=true;
}
if(onBoat==true & Input.GetKeyUp(KeyCode.L)==true){
right=false;
}
if(forward==true){
//transform.Translate(Vector3.right*Time.deltaTime*5);
//move forward (right =forward in this gameobjects case
boatr.AddForce(transform.right*Time.deltaTime*5000);
}
if(left==true){
//rotate left
transform.RotateAround(position.transform.position,Vector3.up,-turnspeed);
}
if(right==true){
//rotate right
transform.RotateAround(position.transform.position,Vector3.up,turnspeed);
}
}
void FixedUpdate(){
//find speed of boat and set turnspeed based on boat speed
speed=((transform.position-lastpos).magnitude)/Time.deltaTime;
lastpos=transform.position;
turnspeed=speed/5.8f;
turnspeed=Mathf.Max(turnspeed,.001f);
turnspeed=Mathf.Min(turnspeed,1f);
}
}
Why are you using &
ins$$anonymous$$d of &&
? Why are you going condition==True
ins$$anonymous$$d of just condition
? Also what is your framerate. If this script takes up 80% either your computer just can't handle anything, or it has nothing else to do!
also you are moving an physics object's rotation outside of FixedUpdate, which isn't great.
Answer by Chronos-L · Mar 22, 2013 at 09:44 AM
This is a very bad way to arrange conditions, try any of these 2 (the 1st is the lazy bum version from lazy people like me, the 2nd is resembles your original script)
if-conditions arrangement 1
void Update () {
transform.position=new Vector3(transform.position.x,9.6f,transform.position.z);
float distance=Vector3.Distance(player.transform.position,transform.position);
if(Input.GetKeyDown(KeyCode.T)){
onBoat=!onBoat;
if ( !onBoat ) {
forward = false;
left = false;
right = false;
}
}
if( onBoat ){
player.transform.position = position.transform.position;
forward = Input.GetKey(KeyCode.I);
left = Input.GetKey(KeyCode.J);
right= Input.GetKey(KeyCode.L);
}
if( left && !right ){ //One button at a time
transform.RotateAround( position.transform.position, Vector3.up, -turnspeed * Time.deltaTime);
}
else if( right && !left ){ //One button at a time
transform.RotateAround( position.transform.position, Vector3.up, turnspeed * Time.deltaTime);
}
}
void FixedUpdate(){
if(forward){
boatr.AddForce(transform.right*Time.deltaTime*5000);
}
speed=((transform.position-lastpos).magnitude)/Time.deltaTime;
lastpos=transform.position;
turnspeed=Mathf.Clamp( speed/5.8f, 0.001f, 1f );
}
if-conditions arrangement 2
void Update () { transform.position=new Vector3(transform.position.x,9.6f,transform.position.z); float distance=Vector3.Distance(player.transform.position,transform.position);
if(Input.GetKeyDown(KeyCode.T)){
onBoat=!onBoat;
if ( !onBoat ) {
forward = false;
left = false;
right = false;
}
}
if(onBoat){
player.transform.position=position.transform.position;
if( Input.GetKeyDown(KeyCode.I) ){
forward=true;
}
else if( Input.GetKeyUp(KeyCode.I) ){
forward=false;
}
if( Input.GetKeyDown(KeyCode.J) ){
left=true;
}
else if( Input.GetKeyUp(KeyCode.J) ){
left=false;
}
if( Input.GetKeyDown(KeyCode.L) ){
right=true;
}
else if( Input.GetKeyUp(KeyCode.L) ){
right=false;
}
}
if( left && !right ){ //One button at a time
transform.RotateAround( position.transform.position, Vector3.up, -turnspeed * Time.deltaTime);
}
else if( right && !left ){ //One button at a time
transform.RotateAround( position.transform.position, Vector3.up, turnspeed * Time.deltaTime);
}
}
void FixedUpdate(){
if(forward){
boatr.AddForce(transform.right*Time.deltaTime*5000);
}
speed=((transform.position-lastpos).magnitude)/Time.deltaTime;
lastpos=transform.position;
turnspeed=Mathf.Clamp( speed/5.8f, 0.001f, 1f );
}
sadly no fps boost and for what ever reason the turning is either extemely slow or not working all together, i know you just moved my if statements around (i've been coding for a while, can't believe i made code that ugly) but for whatever reason it has stopped rotating the boat. The profiler says that the rota$$anonymous$$rond method is taking up all the cpu, is there a physics function that is equivalent, i tried add torque but the boat is locked in x,y,z rotation so it doesnt go in odd direction and using torque would require me to disable those locks and i don't know how to prevent the boat from going in odd flips without the locks (such as flipping nose down).
P.S i use ==true just cuz it's easier to read, and i moved from java (not javascipt) which uses & for if statements, also it's not 80% cpu,i may have been unclear about that, but 80% of the processing that the game uses, also the fps while on boat (only while turning is 34, else it's 75) , while doing anything else 75,due to vsync, and my computer is very fast (i5-2500k @4.0GHz, gtx 465, 16gb 1600$$anonymous$$Hz ram,water cooled,etc)
On close inspection:
transform.RotateAround( position.transform.position, Vector3.up, -turnspeed * Time.deltaTime);
You rotate your boat using the +Y axis(Vector3.up) while using the position.transform.position as pivot point. Where is your pivot then? Is it at the back end the boat?
If your rotate pivot is very close to the boat center, will this line do any difference in FPS?
transform.Rotate(Vector3.up, -turnspeed * Time.deltaTime);
there is no fps drop when using rotate but there is unrealistic movement (thats why i moved to rotate around in the first place) and also the axis are weird, Vector3.up turns it along x axis
transform.Rotate(Vector3.up, -turnspeed * Time.deltaTime, Space.World);
This should fix the orientation, but not your problem.
However, you are certain that the transform.RotateAround()
is causing the FPS drop. I would recommend you to close down this question, reopen another question with this new script and screenshots on your profiler.
Name the new question with a better title, something like "Function causing FPS drop" or "Transform.RotateAround affects performace". Use a more specific tag: "performace", "lag" etc. Hope that this will bring in users with experience in these topics to help you.