I am making my first game in Unity 3D something like tower defense game. I have imported a Fbx model of a tower and attached it to a prefab. Now I want the nozzle of the tower to rotate and follow the enemy as the enemy passes by .
In the fbx model i imported i got I have two poly meshes one for the base of the tower that is fixed, and one for the top of the tower that will rotate. Now I tried to create two different gameObject with these two meshes but if I put them on same point they overlap. So I have to do manual alignment such that the nozzle sit correctly over the base.
I was wondering if there is any other way such that entire towers remain is one gameObject and I can rotate the upper part.
I did manage to solve my problem. Not sure if was the best way , but it works.
To upgrade the towers and transform only the nozzle part I essentially did this.
public class tryFbx : MonoBehaviour {
public GameObject[] ModelPrefab;
GameObject modelInstance;
Renderer rn = new Renderer();
// Attaching the model to prefab at runtime by creating a array of prefabs
public void AttachModelToPrefab(GameObject modelPrefab) {
modelInstance = GameObject.Instantiate(modelPrefab) as GameObject;
modelInstance.transform.position = transform.position;
modelInstance.transform.rotation = transform.rotation;
// Attach the model instance to the prefab shell
modelInstance.transform.parent = gameObject.transform;
}
void Start () {
}
// Update is called once per frame
void Update () {
if (GameManager.upgrade){
AttachModelToPrefab(ModelPrefab[GameManager.towerUpgradeLevel]);
foreach ( Renderer r in modelInstance.GetComponentsInChildren<Renderer>()){
// "polySurface98" is the name of the mesh I want to rotate. The tower and its upgrade have the same name.
if (r.name == "polySurface98")
rn = r;
}
// apply any transformation to the partial fbx
rn.transform.Translate(1,1,1);
}
}
}
You can create a hierarchy of GameObjects; you'll have one parent GameObject representing the tower and 2 children, being that you rotate one of them. Note that the coordinates of the children will be in relation to the parent's, so any "messy" manual calibration you make on the children will be contained.
Or, more complicated, you can create only one mesh that has an animation and apply it to one GameObject.
Related
enter image description here I am instantiating prefabs and listing them on a scroll list. I am trying to teleport the player to instantiated prefab position when I click its reference on scroll list listing?
All suggestions are welcome.
From what I understand about your problem (explained in the comments rather than the question), you should be able to do this:
You can instantaneously move an object camera by setting its transform's position to the instantiated prefab's position when the click has occurred. For a camera, you probably have the camera view in X and Y dimension, so you want to move it to the new X and Y position but leave the Z-position as it is.
One potential solution: Add the following script to the GameObject with your Button component. Then add an event-listener on the Button component that points to the newly added script component and choose the MyTeleportingButton.OnClick as the target method. You also need to drag in the camera as a reference in the new script component.
public class MyTeleportingButton : MonoBehaviour
{
public GameObject camera;
public void OnClick()
{
// casting to Vector2 in order to move in 2D only
var currentPosition = camera.transform.position;
var newPosition = transform.position;
// set same depth as camera
newPosition.z = currentPosition.z;
camera.transform.position = newPosition;
}
}
I am attempting to create a 2d top-down car racing game. This game will have a random road map each time the player plays the game. I have thought about doing this in two different ways: A tilemap, or just generate the roads by placing different prefabs (straight roads, turns, etc). I have decided to go with the prefab route.
The way I believe it should work is to have prefab square "tiles" which have their own colliders set on the edges so I can tell if a player goes off the track in which case they blow up. I would have a MapGenerator Script which will generate an initial random map by keeping track of the last tile placed (including its location and road type: left turn, straight, right, etc). This script will then keep adding onto the road randomly as the player gets closer and closer to the end which makes it an infinite road.
I just want to know if this is just not efficient or if I am thinking of this completely wrong.
Here are a couple of images showing my road tiles which I made in photoshop and then one prefab for a straight road (take note of the colliders on its edges).
A similar game to one I want to make is Sling Drift which I can provide the link if you want. I don't know the policy on adding links to forum chat.
Also, here is my code for the map generator:
//Type of tyle, types are normal (straight road or horizontal road) and turns
public enum MapTileType
{
NORMAL,
N_E,
N_W,
S_E,
S_W
}
//structure for holding the last tile location and its type.
public struct TypedTileLocation
{
public TypedTileLocation(Vector2 pos, MapTileType tyleType)
{
m_tileType = tyleType;
m_position = pos;
}
public Vector2 m_position;
public MapTileType m_tileType;
}
public class MapGenerator : MonoBehaviour
{
//Map Tiles
public GameObject m_roadTile;
public GameObject m_turnNorthWestTile;
//holds all the tiles made in the game
private List<GameObject> m_allTiles;
//Map Tile Widths and Height
private float m_roadTileWidth, m_roadTileHeight;
//Used for generating next tile
TypedTileLocation m_lastTilePlaced;
private void Awake()
{
//store the initial beginning tile location (0,0)
m_lastTilePlaced = new TypedTileLocation(new Vector2(0,0), MapTileType.NORMAL);
//set height and width of tiles
m_roadTileWidth = m_roadTile.GetComponent<Renderer>().bounds.size.x;
m_roadTileHeight = m_roadTile.GetComponent<Renderer>().bounds.size.y;
m_allTiles = new List<GameObject>();
}
// Start is called before the first frame update
void Start()
{
SetupMap();
}
void SetupMap()
{
//starting at the beginning, just put a few tiles in straight before any turns occur
for (int i = 0; i < 6; ++i)
{
GameObject newTempTile = Instantiate(m_roadTile, new Vector2(0, m_roadTileHeight * i), Quaternion.identity);
m_lastTilePlaced.m_tileType = MapTileType.NORMAL;
m_lastTilePlaced.m_position.x = newTempTile.transform.position.x;
m_lastTilePlaced.m_position.y = newTempTile.transform.position.y;
m_allTiles.Add(newTempTile);
}
//now lets create a starter map of 100 road tiles (including turns and straigt-aways)
for (int i = 0; i < 100; ++i)
{
//first check if its time to create a turn. Maybe I'll randomly choose to either create a turn or not here
//draw either turn or straight road, if the tile was a turn decide which direction we are now going (N, W, E, S).
//this helps us determine which turns we can take next
//repeat this process.
}
}
void GenerateMoreMap()
{
//this will generate more map onto the already existing road and then will delete some of the others
}
// Update is called once per frame
void Update()
{
}
private void OnDrawGizmos()
{
}
}
Thanks!
Have you tried splines? They let you make curvy paths like race tracks easily. If not, here is a video that might help: https://www.youtube.com/watch?v=7j_BNf9s0jM.
I have a ball which we can throw here and there in my game. I want my cinemachine vcam to move only in the x direction with the ball. And just look up to the ball while its in air. I don't want the camera to move in y direction along it too.
I have set the look at and follow fields to the ball only. All i want it the camera to not follow the ball in y. (Basically, follow the ball in x, and keep looking at it in the air)
How can I achieve this is the most trivial and beautiful way possible? (open to scripts, but the lesser code the better)
as i've just tested, You can write a script that attaches to your camera, where you create a new vector3 with the x of your ball, and the frozen Y values that you want here's an exemple:
public class CameraController : MonoBehaviour
{
//Assign your ball in the inspector
public Transform target;
// Update is called once per frame
void Update()
{
//Here i assumed that you want to change the X
Vector3 newCamPosition = new Vector3(target.position.x, yourValue, yourValue);
gameObject.transform.position = newCamPosition;
}
}
Hope It helped <3
I created a pin object by script attached it to a sphere object .
using UnityEngine;
public class InstantiateMarkerPin : MonoBehaviour
{
public float Xpos;
public float Ypos;
public float Zpos;
public GameObject gameObjectPinInstantiate;
// Start is called before the first frame update
private void Start()
{
Xpos = 0.09f;
Ypos = 0.50f;
Zpos = 1.1f;
//The original object, where to instantiate, and the orientation of the new object
GameObject marker = (GameObject)Resources.Load("gameObjectPin");
Vector3 location = new Vector3(Xpos, Ypos, Zpos);
Quaternion rotation = Quaternion.Euler(0, 0, 0);
//The object the script is attached to
GameObject world = this.gameObject;
//Instantiate the prefab
gameObjectPinInstantiate = Instantiate(marker, location, rotation, world.transform);
Debug.Log("InstantiateMarkerPin class : Marker Location 2 :X, Y, Z : " + gameObjectPinInstantiate.transform.position);
}
// Update is called once per frame
private void Update()
{
}
}
This script is attached to the sphere Object .My sphere Object have shader material of earth image (globe).
This Instantiated Prefabs (gameObjectPin) on sphere surface appears on scene but not on game screen ,When I select the camera object in the camera preview also this object does not appear .
Scene view
Scene View when camera is selected
I am new to Unity what should I check or correct to appear my created object on the sphere
basically I am trying to add pins to corresponding country and label it .Similar to the globe on this http://kitsdmcc.com/news
Gameobject is created when Play is clicked on the sphere object
When the Pin Object is selected on play mode
Oh now I see it! What you did was only setting its GIZMO via this menu
which is only displayed in the SceneView.
This has nothing to do with the rendering in the GameView but is just a way for easier seeing and finding certain types of objects in the SceneView since usually they would be invisible if not selected.
From the Glossary:
A graphic overlay associated with a GameObject
in a Scene
, and displayed in the Scene View
. Built-in scene
tools such as the move tool are Gizmos
, and you can create custom Gizmos using textures or scripting. Some Gizmos are only drawn when the GameObject is selected, while other Gizmos are drawn by the Editor regardless of which GameObjects
are selected.
As noted in the comments there is no Component at all on your GameObject so nothing is rendered in the Gameview.
Of course now you could enable Gizmos also for the GameView via the Gizmos toggle
but I guess what you rather are trying to achieve is rather rendering that icon in the final App.
You probably would like to use e.g. the SpriteRenderer component here. And simply drag in your Icon to the Sprite property.
You might have to change the Pin Texture's TextureType to Sprite (2D and UI).
In general I would also recommend to Create a Prefab instead of using the Resources folder here.
There are also some changes I would do to your code in general:
public class InstantiateMarkerPin : MonoBehaviour
{
[Header("Settings")]
// directly use a Vector3 for setting the values
// | default value for this field
// | (only valid until changed via Inspector!)
// v
public Vector3 TargetPosition = new Vector3(0.09f, 0.5f, 1.1f);
// Instead of using Resources simply reference the
// created Prefab here
public GameObject gameObjectPinPrefab;
[Header("Outputs")]
public GameObject gameObjectPinInstantiate;
private void Start()
{
// Careful this currently ovewrites any value set via the
// Inspector. Later you will probably want to remove this.
TargetPosition = new Vector3(0.09f, 0.5f, 1.1f);
//As said I would rather use a prefab here and simply reference it above in the field
//gameObjectPinPrefab = (GameObject)Resources.Load("gameObjectPin");
//Instantiate the prefab
gameObjectPinInstantiate = Instantiate(gameObjectPinPrefab, TargetPosition, Quaternion.identity, transform);
Debug.Log("InstantiateMarkerPin class : Marker Location 2 :X, Y, Z : " + gameObjectPinInstantiate.transform.position);
}
// Always remove empty Unity methods
// They are called as messages if they exist
// and only cause unnecessary overhead
}
I need grip between two objects actually small cube is a player having rigid body and big cube is an object that helps small cube to jump on it and keep jumping on other big cubes to reach to the destination. I need when the player jumps and land on rotating cube so there should friction between them by default the player should rotate with big cube cause its on the big cube.
The expected result was that the small cube having rigid body should also rotate with big cube cause big cube is rotating and is on the big cube:
You can set the small cube gameobject as child of the big cube gameobject. This should to the trick.
----EDIT AFTER COMMENTS
If you need to change the child hiearchy (because the small cube can move away), then you need a script that add and remove the child when required.
=> When player (small cube) is on the big cube you much child player to the big cube.
=> When player (small cube) moves away of the big cube you much de-child player to the big cube.
If you're using rigidbodies you may use OnCollisionEnter and OnCollisionExit.
You may attach this monobehaviour to the big cube.
public class BigCubeScript : MonoBehaviour
{
private void OnCollisionEnter(Collision other)
{
//check if the colliding object is player (here I'm using a tag, but you may check it as you prefer)
if (other.gameObject.tag == "Player")
//change the parent of the player, setting it as this cube
other.transform.SetParent(this.transform);
}
void OnCollisionExit(Collision other)
{
if (other.gameObject.tag == "Player")
//remove the player from the cube
other.transform.SetParent(null);
}
}
You can also apply a force to the rotation of the player until he stays on the cube. In this case it's quite important to balance the rotation force well (you can try it in the editor).
public class BigCubeScript : MonoBehaviour
{
//you may change this to add or remove the force
Vector3 _rotationForce = new Vector3(0, 5, 0);
private void OnCollisionStay(Collision other)
{
var rigidbody = other.gameObject.GetComponent<Rigidbody>();
Quaternion deltaRotation = Quaternion.Euler(_rotationForce * Time.deltaTime);
rigidbody.MoveRotation(rigidbody.rotation * deltaRotation);
}
}
Further info in OnCollisioEnter and OnCollisionExit in this Unity Tutorial
Further info on the Tags in this Unity Tutorial
You could try to constrain position and rotation on Rigidbody of the small cube. After that you could call constrains.none so that you could allow jump again and do that every time the small cube collides with the big one. Hope it helps :)