I am making a game(2D) in which an object runs with a velocity and jumps onto the coming platforms and I have made the camera as the child of the game object(i.e the main player) in the hierarchy. The problem is that whenever my game object get rotated on striking the platform or obstacle the main camera also starts getting rotated. I am unable to sort out this problem, Can anyone help with this?
You can either lock rotation for the Camera in the Inspector or you create a Camerascript to follow you player manuell. Seconed is better because you can easily add smoothe, deadzones or camera effects like shake on dmg taken to the camera.
Example for the script from the unity page:
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour
{
public GameObject player; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start ()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate ()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
transform.position = player.transform.position + offset;
}
}
Add this script to your MainCamera. Then drage your PlayerObject into the Field "player" in the camera Inspector.
If you need further help watch this video here
Related
We are using ExoPlayer to play m3u8 files (stream) on Android TV. The streaming is working fine, but the video plays in portrait mode (even if the video is shot in landscape).
Looks like some issue with orientation of the android TV instead of aspect ratio.
private fun initializePlayer() {
if(mPlayer == null) {
playerView = activity!!.findViewById<SimpleExoPlayerView>(R.id.texture_view)
// playerView!!.setControllerVisibilityListener(this)
playerView!!.requestFocus()
val bandwidthMeter = DefaultBandwidthMeter()
val videoTrackSelectionFactory = AdaptiveTrackSelection.Factory(bandwidthMeter)
mTrackSelector = DefaultTrackSelector(videoTrackSelectionFactory)
mPlayer = ExoPlayerFactory.newSimpleInstance(activity, mTrackSelector)
playerView!!.player= mPlayer
mPlayerAdapter = LeanbackPlayerAdapter(activity, mPlayer, UPDATE_DELAY)
mPlayerGlue = VideoPlayerGlue(activity!!, mPlayerAdapter!!)
mPlayerGlue!!.host = VideoSupportFragmentGlueHost(this)
mPlayerGlue!!.playWhenPrepared()
play(s1)
}
}
Commenting these lines :
mPlayerAdapter = LeanbackPlayerAdapter(activity, mPlayer, UPDATE_DELAY)
mPlayerGlue = VideoPlayerGlue(activity!!, mPlayerAdapter!!)
mPlayerGlue!!.host = VideoSupportFragmentGlueHost(this)
mPlayerGlue!!.playWhenPrepared()
Plays the video in landscape but the player controls are hidden and it only plays the lowest quality of the video. Please help us with this.
Metadata of the MP4 video contains a property called Rotation=90° but it's ignored by the ExoPlayer. To fix it you need to inject this Java function into your code:
void onVideoSizeChanged(int width,
int height,
int unappliedRotationDegrees, // 90° or 270°
float pixelWidthHeightRatio);
This allows an application using TextureView to easily apply the rotation by making the appropriate call to TextureView.setTransform. Note that on Lollypop+ unappliedRotationDegrees will always be equal to 0.
You can find this function on a line #74 at MediaCodecVideoTrackRenderer page of GitHub.
If the above-mentioned method doesn't work for you, you may find another remedy in Rotation Issue #91 post on a GitHub.
As far i know, exoplayer will generate its size based on texture view size. So try to programmatically resize your texture view by
playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
and also try to resize your player programmatically
mPlayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
Hope this will help.
I am creating a small game in the Unity game engine, and the map for the game is generated from a 2d tilemap. The tilemap contains so many tiles, though, is is very hard for a device like a phone to render them all, so the frame rate drops. The map is completely static in that the only moving thing in the game is a main character sprite and the camera following it. The map itself has no moving objects, it is very simple, there must be a way to render only the needed sections of it or perhaps just render the map in once. All I have discovered from researching the topic is that perhaps a good way to do it is buy using the Unity mesh class to turn the tilemap into a mesh. I could not figure out how to do this with a 2d tilemap, and I could not see how it would benefit the render time anyways, but if anyone could point me in the right direction for rendering large 2d tilemaps that would be fantastic. Thanks.
Tile system:
To make the tile map work I put every individual tile as a prefab in my prefab folder, with the attributes changed for 2d box colliders and scaled size. I attribute each individual prefab of the tile to a certain color on the RGB scale, and then import a png file that has the corresponding colors of the prefabs where I want them like this:
I then wrote a script which will place each prefab where its associated color is. It would look like this for one tile:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Map : MonoBehaviour {
private int levelWidth;
private int levelHeight;
public Transform block13;
private Color[] tileColors;
public Color block13Color;
public Texture2D levelTexture;
public PlayerMobility playerMobility;
// Use this for initialization
void Start () {
levelWidth = levelTexture.width;
levelHeight = levelTexture.height;
loadLevel ();
}
// Update is called once per frame
void Update () {
}
void loadLevel(){
tileColors = new Color[levelWidth * levelHeight];
tileColors = levelTexture.GetPixels ();
for (int y = 0; y < levelHeight; y++) {
for (int x = 0; x < levelWidth; x++) {
// if (tileColors [x + y * levelWidth] == block13Color) {
// Instantiate(block13, new Vector3(x, y), Quaternion.identity);
// }
//
}
}
}
}
This results in a map that looks like this when used with all the code (I took out all the code for the other prefabs to save space)
You can instantiate tiles that are in range of the camera and destroy tiles that are not. There are several ways to do this. But first make sure that what's consuming your resources is in fact the large number of tiles, not something else.
One way is to create an empty parent gameObject to every tile (right click in "Hierarchy" > Create Empty"
then attach a script to this parent. This script has a reference to the camera (tell me if you need help with that) and calculates the distance between it and the camera and instantiates the tile if the distance is less than a value, otherwise destroys the instance (if it's there).
It has to do this in the Update function to check for the distances every frame, or you can use "Coroutines" to do less checks (more efficient).
Another way is to attach a script to the camera that has an array with instances of all tiles and checks on their distances from the camera the same way. You can do this if you only have exactly one large tilemap because it would be hard to re-use this script if you have more than a large tilemap.
Also you can calculate the distance between the tile and the character sprite instead of the camera. Pick whichever is more convenient.
After doing the above and you still get frame-drops you can zoom-in the camera to include less tiles in its range but you'd have to recalculate the distances then.
I'm programming a game with LibGDX and Box2D and I want my camera to follow my player. But as I zoom in (because Box2Ds metric system, using camera.zoom = x) the camera is shifted when the player moves (the camera follows the player):
Shifted View
Normal View
That only happens when the player moves, so there can't be a problem with the coordinates. My Question is how to remove this shifting as the player moves.
Here's some of my code:
Render Loop (excerpt):
#Override
public void render(float delta) {
//set the camera position to player's position
cam.position.set(player_body.getWorldCenter().x, player_body.getWorldCenter().y, 0);
cam.update();
world.step(Gdx.graphics.getDeltaTime(), 6, 2);
world.clearForces();
handleInput();
Gdx.gl.glClearColor(.05f, .05f, .05f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(cam.combined);
debugRenderer.render(world, cam.combined);
}
Make the player move:
if (Gdx.input.isKeyPressed(Keys.W)) {
player_body.setLinearVelocity(transX, transY);
player.setMoving(true);
}
Setup a simple scene here:
http://jsfiddle.net/majman/Sps3c/
I was initially trying to demonstrate a problem I was having with rotating a parent container while having the camera maintain it's relative offset position, but when setting up this example I couldn't even adjust the camera's initial position.
Current Problem:
// camera
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 5, 150);
camera.position.z = 50; // this doesn't work?
// object to contain camera & helper
cameraContainer = new THREE.Object3D();
cameraContainer.rotation.order = "YXZ"; // maybe not necessary
// add to container
cameraContainer.add(camera);
scene.add(cameraContainer);
Now when rotating the cameraContainer, the camera's rotation follows - but I'd like the camera's position to be offset from the cameraContainer. I'm unable to modify any position properties for some reason.
Your code is working fine. You are confused because the CameraHelper is not displaying the camera in its actual position. You need to add the CameraHelper as a child of the scene.
// camera helper
cameraHelper = new THREE.CameraHelper( camera2 );
scene.add( cameraHelper );
updated fiddle: http://jsfiddle.net/Sps3c/1/
Tip: I added an OrbitController to your demo for a better view of the situation.
three.js r.66
Suppose I have an array of objects Ball that are floating around in the canvas, and if an object is clicked, it will disappear. I am having a hard time thinking how to know if an object is clicked. Should I use for loop to loop through if the mouse position is within the area of those objects? But I am afraid that will slow down the progress. What is a plausible algorithm to achieve this?
Keep track of the various centre points and radius of the Balls, and whenever a mouse click happens, calculate the distance of the mouse co-ordinates to the other balls centres. If any distance comes out to be within the radius of the particular ball, that means that, that particular ball was clicked.
public class Ball {
private Point centre;
private int radius;
public boolean isInVicinityOf(int x, int y)
{
// There are faster ways to write the following condition,
// but it drives the point I'm making.
if(Math.hypot(centre.getX() - x, centre.getY() - y) < radius)
return true;
return false;
}
// ... other stuff
}
Here's a code for checking if mouse click happened on any ball:
// Returns the very first ball object which was clicked.
// And returns null if none was clicked.
public Ball getBallClicked(Ball[] balls, MouseEvent event)
{
for (Ball ball : balls)
{
if(ball.isInVicinityOf(event.getX(), event.getY()))
{
return ball;
}
}
return null;
}
There are many other ways to go about implementing the same thing, like by using Observer pattern and others, but above is one of those approach.
Hope it helps.
Use void mouseClicked() it then specify its cordinates on the screen. You can specify what you want to do with the object in an if-statement in that void.