I'm having a hard time to pan a view of a gameObject in Unity3d. I'm new to scripting and I'm trying to develop an AR (Augmented Reality) application for Android.
I need to have a gameObject (e.g. a model of a floor), from the normal top down view, rendered to a "pseudo" iso view, inclined to 45 degrees. As the gameObject is inclined, I need to have a panning function on its view, utilizing four (4) buttons (for left, right, forward(or up), backward(or down)).
The problem is that, I cannot use any of the known panning script snippets around the forum, as the AR camera has to be static in the scene.
Need to mention that, I need the panning function to be active only at the isometric view, (which I already compute with another script), not on top down view. So there must be no problem with the inclination of the axes of the gameObject, right?
Following, are two mockup images of the states, the gameObject (model floor) is rendered and the script code (from Unity reference), that I'm currently using, which is not very much functional for my needs.
Here is the code snippet, for left movement of the gameObject. I use the same with a change in -, +speed values, for the other movements, but I get it only move up, down, not forth, backwards:
#pragma strict
// The target gameObject.
var target: Transform;
// Speed in units per sec.
var speedLeft: float = -10;
private static var isPanLeft = false;
function FixedUpdate()
{
if(isPanLeft == true)
{
// The step size is equal to speed times frame time.
var step = speedLeft * Time.deltaTime;
// Move model position a step closer to the target.
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}
static function doPanLeft()
{
isPanLeft = !isPanLeft;
}
It would be great, if someone be kind enough to take a look at this post, and make a suggestion on how this functionality can be coded the easiest way, as I'm a newbie?
Furthermore, if a sample code or a tutorial can be provided, it will be appreciated, as I can learn from this, a lot. Thank you all in advance for your time and answers.
If i understand correctly you have a camera with some fixed rotation and position and you have a object you want to move up/down/left/right from the cameras perspective
To rotated an object to a set of angles you simply do
transform.rotation = Quaternion.Euler(45, 45, 45);
Then to move it you use the cameras up/right/forward in worldspace like this to move it up and left
transform.position += camera.transform.up;
transform.position -= camera.transform.right;
If you only have one camera in your scene you can access its transform by Camera.main.transform
An example of how to move it when someone presses the left arrow
if(Input.GetKeyDown(KeyCode.LeftArrow))
{
transform.position -= camera.transform.right;
}
I am attempting to translate an object depending on the touch position of the user.
The problem with it is, when I test it out, the object disappears as soon as I drag my finger on my phone screen. I am not entirely sure what's going on with it?
If somebody can guide me that would be great :)
Thanks
This is the Code:
#pragma strict
function Update () {
for (var touch : Touch in Input.touches)
{
if (touch.phase == TouchPhase.Moved) {
transform.Translate(0, touch.position.y, 0);
}
}
}
The problem is that you're moving the object by touch.position.y. This isn't a point inworld, it's a point on the touch screen. What you'll want to do is probably Camera.main.ScreenToWorldPoint(touch.position).y which will give you the position inworld for wherever you've touched.
Of course, Translate takes a vector indicating distance, not final destination, so simply sticking the above in it still won't work as you're intending.
Instead maybe try this:
Vector3 EndPos = Camera.main.ScreenToWorldPoint(touch.position);
float speed = 1f;
transform.position = Vector3.Lerp(transform.position, EndPos, speed * Time.deltaTime);
which should move the object towards your finger while at the same time keeping its movements smooth looking.
You'll want to ask this question at Unity's dedicated Questions/Answers site: http://answers.unity3d.com/index.html
There are very few people that come to stackoverflow for Unity specific question, unless they relate to Android/iOS specific features.
As for the cause of your problem, touch.position.y is define in screen space (pixels) where as transform.Translate is expecting world units (meters). You can convert between the two using the Camera.ScreenToWorldPoint() method, then creating a vector out of the camera position and screen world point. With this vector you can then either intersect some geometry in the scene or simply use it as a point in front of the camera.
http://docs.unity3d.com/Documentation/ScriptReference/Camera.ScreenToWorldPoint.html
Hey all I'm at a crossroads with my app that I've been working on.
It's a game and an 'arcade / action' one at that, but I've coded it using Surfaceview rather than Open GL (it just turned out that way as the game changed drastically from it's original design).
I find myself plagued with performance issues and not even in the game, but just in the first activity which is an animated menu (full screen background with about 8 sprites floating across the screen).
Even with this small amount of sprites, I can't get perfectly smooth movement. They move smoothly for a while and then it goes 'choppy' or 'jerky' for a split second.
I noticed that (from what I can tell) the background (a pre-scaled image) is taking about 7 to 8 ms to draw. Is this reasonable? I've experimented with different ways of drawing such as:
canvas.drawBitmap(scaledBackground, 0, 0, null);
the above code produces roughly the same results as:
canvas.drawBitmap(scaledBackground, null, screen, null);
However, if I change my holder to:
getHolder().setFormat(PixelFormat.RGBA_8888);
The the drawing of the bitmap shoots up to about 13 MS (I am assuming because it then has to convert to RGB_8888 format.
The strange thing is that the rendering and logic move at a very steady 30fps, it doesn't drop any frames and there is no Garbage Collection happening during run-time.
I've tried pretty much everything I can think of to get my sprites moving smoothly
I recently incorporated interpolation into my gameloop:
float interpolation = (float)(System.nanoTime() + skipTicks - nextGameTick)
/ (float)(skipTicks);
I then pass this into my draw() method:
onDraw(interpolate)
I have had some success with this and it has really helped smooth things out, but I'm still not happy with the results.
Can any one give me any final tips on maybe reducing the time taken to draw my bitmaps or any other tips on what may be causing this or do you think it's simply a case of Surfaceview not being up to the task and therefore, should I scrap the app as it were and start again with Open GL?
This is my main game loop:
int TICKS_PER_SECOND = 30;
int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
int MAX_FRAMESKIP = 10;
long next_game_tick = GetTickCount();
int loops;
bool game_is_running = true;
while( game_is_running ) {
loops = 0;
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
update_game();
next_game_tick += SKIP_TICKS;
loops++;
}
interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
/ float( SKIP_TICKS );
display_game( interpolation );
}
Thanks
You shouldn't use Canvas to draw fast sprites, especially if you're drawing a fullscreen image. Takes way too long, I tell you from experience. I believe Canvas is not hardware accelerated, which is the main reason you'll never get good performance out of it. Even simple sprites start to move slow when there are ~15 on screen. Switch to OpenGL, make an orthographic projection and for every Sprite make a textured quad. Believe me, I did it, and it's worth the effort.
EDIT: Actually, instead of a SurfaceView, the OpenGL way is to use a GLSurfaceView. You create your own class, derive from it, implement surfaceCreated, surfaceDestroyed and surfaceChanged, then you derive from Renderer too and connect both. Renderer handles an onDraw() function, which is what will render, GLSurfaceView manages how you will render (bit depth, render modes, etc.)
i want to use libgdx as a solution to scaling of apps based on screens aspect ratio.
i've found this link , and i find it really useful:
http://blog.acamara.es/2012/02/05/keep-screen-aspect-ratio-with-different-resolutions-using-libgdx/
i'm quite rusty with opengl (haven't written for it in years) and i wish to use the example on this link so that it would be easy to put images and shapes .
sadly , the starting point is in the middle . i want to use it like on many other platforms - top left corner should be (0,0) , and bottom right corner should be (targetWidth-1,targetHeight-1) ,
from what i remember, i need to move(translate) and rotate the camera in order to achieve it , but i'm not sure .
here's my modified code of the link's example for the onCreate method:
#Override
public void create()
{
camera=new OrthographicCamera(VIRTUAL_WIDTH,VIRTUAL_HEIGHT);
// camera.translate(VIRTUAL_WIDTH/2,VIRTUAL_HEIGHT/2,0);
// camera.rotate(90,0,0,1);
camera.update();
//
font=new BitmapFont(Gdx.files.internal("data/fonts.fnt"),false);
font.setColor(Color.RED);
//
screenQuad=new Mesh(true,4,4,new VertexAttribute(Usage.Position,3,"attr_position"),new VertexAttribute(Usage.ColorPacked,4,"attr_color"));
Point bottomLeft=new Point(0,0);
Point topRight=new Point(VIRTUAL_WIDTH,VIRTUAL_HEIGHT);
screenQuad.setVertices(new float[] {//
bottomLeft.x,bottomLeft.y,0f,Color.toFloatBits(255,0,0,255),//
topRight.x,bottomLeft.y,0f,Color.toFloatBits(255,255,0,255),//
bottomLeft.x,topRight.y,0f,Color.toFloatBits(0,255,0,255),//
topRight.x,topRight.y,0f,Color.toFloatBits(0,0,255,255)});
screenQuad.setIndices(new short[] {0,1,2,3});
//
bottomLeft=new Point(VIRTUAL_WIDTH/2-50,VIRTUAL_HEIGHT/2-50);
topRight=new Point(VIRTUAL_WIDTH/2+50,VIRTUAL_HEIGHT/2+50);
quad=new Mesh(true,4,4,new VertexAttribute(Usage.Position,3,"attr_position"),new VertexAttribute(Usage.ColorPacked,4,"attr_color"));
quad.setVertices(new float[] {//
bottomLeft.x,bottomLeft.y,0f,Color.toFloatBits(255,0,0,255),//
topRight.x,bottomLeft.y,0f,Color.toFloatBits(255,255,0,255),//
bottomLeft.x,topRight.y,0f,Color.toFloatBits(0,255,0,255),//
topRight.x,topRight.y,0f,Color.toFloatBits(0,0,255,255)});
quad.setIndices(new short[] {0,1,2,3});
//
texture=new Texture(Gdx.files.internal(IMAGE_FILE));
spriteBatch=new SpriteBatch();
spriteBatch.getProjectionMatrix().setToOrtho2D(0,0,VIRTUAL_WIDTH,VIRTUAL_HEIGHT);
}
so far , i've succeeded to use this code in order to use scaled coordinates , and still keep aspect ratio (which is great) , but i didn't succeed in moving the starting point (0,0) to the top left corner .
please help me .
EDIT: ok , after some testing , i've found out that the reason for it not working is that i use the spriteBatch . i think it ignores the camera . this code occurs in the render part. no matter what i do to the camera , it will still show the same results.
#Override
public void render()
{
if(Gdx.input.isKeyPressed(Keys.ESCAPE)||Gdx.input.justTouched())
Gdx.app.exit();
// update camera
// camera.update();
// camera.apply(Gdx.gl10);
// set viewport
Gdx.gl.glViewport((int)viewport.x,(int)viewport.y,(int)viewport.width,(int)viewport.height);
// clear previous frame
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
//
final String msg="test";
final TextBounds textBounds=font.getBounds(msg);
spriteBatch.begin();
screenQuad.render(GL10.GL_TRIANGLE_STRIP,0,4);
quad.render(GL10.GL_TRIANGLE_STRIP,0,4);
Gdx.graphics.getGL10().glEnable(GL10.GL_TEXTURE_2D);
spriteBatch.draw(texture,0,0,texture.getWidth(),texture.getHeight(),0,0,texture.getWidth(),texture.getHeight(),false,false);
spriteBatch.draw(texture,0,VIRTUAL_HEIGHT-texture.getHeight(),texture.getWidth(),texture.getHeight(),0,0,texture.getWidth(),texture.getHeight(),false,false);
font.draw(spriteBatch,msg,VIRTUAL_WIDTH-textBounds.width,VIRTUAL_HEIGHT);
spriteBatch.end();
}
These lines:
camera.translate(VIRTUAL_WIDTH/2,VIRTUAL_HEIGHT/2,0);
camera.rotate(90,0,0,1);
should move the camera such that it does what you want. However, my code has an additional:
camera.update()
call after it calls translate, and it looks like you're missing that. The doc for Camera.update says:
update
public abstract void update()
Recalculates the projection and view matrix of this camera and the Frustum planes. Use this after you've manipulated any of the attributes of the camera.