I am currently creating a 2D-game in Unity and facing troubles in level design. I would like to create about 100 levels, each with different prefabs at different positions.
In order to load up the proper levels I have built an architecture with scriptable objects. Tilemaps are being used to represent obstacles. So it is possible to have about 30 different tile-positions for each level. It seems wrong to me to fill in those informations on every scriptable object seperatly.
What I am now looking for is a way to create a level in the editor and save the data directly in a scriptable object. To have a button in editor which says: "Save current scene-layout in e.g. scriptable object level 3". And also being able to load every level to the scene in editor mode.
You create your level in a prefab and reference this prefab into your ScriptableObject.
So your level prefab contains your tilemap and other prefabs.
I would suggest Raphael solutions, but in some cases this can be hard if you are deal with prefabs issues.
Other way to achive this would be create your custom editor to iterate your scene and create this ScriptableObject.
I use this code for something similar
GameObject __PARENT = GameObject.Find("__PARENT");
Vector3 centroid = Vector3.zero;
Transform[] childs = __PARENT.transform.GetComponentsInChildren<Transform>();
foreach (Transform go in childs)
{
Debug.Log(go.name);
centroid += go.position;
}
centroid /= (__PARENT.transform.childCount);
GameObject centerPivotObject = new GameObject();
centerPivotObject.name = "CenterPivotObject";
centerPivotObject.transform.position = centroid;
foreach (Transform go in childs)
{
go.parent = centerPivotObject.transform;
}
In my case I was trying to center pivot in parent object, but you can combine this iterate over your parent game using this and create using this your ScriptableObject
https://wiki.unity3d.com/index.php/CreateScriptableObjectAsset
Related
I want to have some prefabs already in the scene and then assign the players each one to control. The Input Manager is pretty clear for assigning prefabs when a player joins, but can this be changed later?
I know I can have a parent game object with several inactive prefabs as children and activate as needed, but this won't work with my current situation. Really need to just switch altogether if possible.
I'd like to use the "join manually" option which requires me to drag prefabs into the scene in the editor, then how do I assign players to them once the scene starts?
Something like:
if (GetComponent<PlayerInput>().playerIndex == 0)
{
"the player becomes prefab 1"
}
if (GetComponent<PlayerInput>().playerIndex == 1)
{
"the player becomes prefab 2"
}
I'm not sure how to access this by code (I'm pretty new) The input manager script appears uneditable, but before I realized this I tried adding some additional public game objects.
If i understand correctly your intend is to keep the players on scene while changing who controls them, right?
You should be able to get the player disconnected an reconnected to a new index without deleting the Player object from scene. Make shure you use methods properly using the docs: Player Input Manager Docs.
Otherwise I think you need an extra layer or some twist. Maybe keep the players on their indexes but change whos controlling the Player GameObjects?
By the way you can instantiate Prefabs by code using Instantiate()
You can also use inheritance to extend PlayerInputManager and maybe add some SwitchPlayer() function if really needed.
public class CustomPIM : PlayerInputManager {}
The custom class will inherit all methods from PlayerInputManager plus whatever you add.
I am new to C# and I am working on an AR project where I am showing directions to a section of books in a library. I have a basic scene set up where the user clicks on a button and something happens. I am using the Mixed Reality Tool Kit's directional indicator. I created 4 game objects that represent different subjects and are placed at different points in space in the scene. I have a directional indicator for each of those game objects and those directional indicators are prefabs. They are an arrow that points to that game object, so what I am trying to do is have them turned off and when the user clicks the button, it turns them on.
Prefabs are just files that contain GameObject, they aren't directly connected to the scene. If you want to create new GameObject from Prefab in runtime you can Instantiate it, and then keep reference to this new GameObject.
You also can check similar question, maybe it will help.
Code example
class SomeClass: MonoBehaviour
{
private GameObject newGameObject;
...
public void InstantiatePrefab(GameObject prefab)
{
newGameObject = Instantiate(prefab, ...);
}
public void SetGameObjectState(bool state)
{
newGameObject.SetActive(state);
}
}
I'm trying to make a list where I can add objects in my scene, later on I'm going to loop through them to determine the closest object to my character and make the character perform certain actions. As soon as I created a list, it won't allow me to add any object to my list or reference it and I don't understand why that's happening. Here's a video to further clarify my issue
List Not working for me
my code for further inquiries
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RobberMechanic : MonoBehaviour
{
public List<GameObject> testing = new List<GameObject>();
// void Start()
// {
// }
// // Update is called once per frame
// void Update()
// {
// }
}
Note: wanted to clarify that my unity version was on 2020.3.1f and now I've tried upgrading to 2020.3.10f and this issue occurs in both versions
what you are trying to do is not possible as you are dragging a gameobject inside your list from the hierarchy onto a prefab in the assets folder. Dragging and dropping works on gameObjects that are already inside the a scene/hierarchy.
To achieve your goal you must either:
Add your Terrorist prefab in the scene. Drag your Sphinx object inside it. The Terrorist prefab will then have the appropriate reference of the gameObject and can be used properly.
Turn your Terrorist object into a scriptable gameObject you can then add all sorts of different properties and will be easier to manage. There are tons of videos and documentation on it as well.
You're trying to add a GameObject from your scene to a list in a Prefab which is not possible, you'll have to drop your prefab into the scene before adding game objects to it or make a Prefab of the object you're trying to add to the list.
I am trying to create an AR app using Unity & Vuforia. I have a 3D model that needs to be spawned when ground plane is detected.But this needs to happen only once.
The way Vuforia work is, it keeps on spawning objects when new plane is detected. So what i need to do is either detect plane only once or spawn the object only once. As i am new to Unity, i need help doing this. Great if someone could tell me what i need to do to achieve this.
Vuforia has updated.Now There is no DeploymentStageOnce script.Inorder to stop duplicating while we touch, we have to turn off Duplicate Stage in Content Positioning Behaviour (Script)Check the Inspector when we click Plane Finder.
In your app you should have a Plane Finder object somewhere with the following properties set by default
The Plane Finder object has a Behaviour component attached that calls a Position Content method if a plane was found. That method belongs to the Content Positioning Behaviour and it makes an instance (Clone) of your Ground Plane Stage. In order to avoid more than one instance you should import the vuforia Deploy Stage Once script located here: https://library.vuforia.com/articles/Solution/ground-plane-guide.html and you should change the Plane Finder Behaviour as the following:
I struggled a long with it, in short we must disable AnchorInputListenerBehaviour after hit.
I attached a new script on PlaneFinder with this code below:
<!-- language-all: c# -->
public void OnInteractiveHitTest(HitTestResult result)
{
var listenerBehaviour = GetComponent<AnchorInputListenerBehaviour>();
if (listenerBehaviour != null)
{
listenerBehaviour.enabled = false;
}
}
I added event on Plane Finder Behavior
That's all, I hope it will be useful.
For Updated Versions:
go to "Advanced" setting and "On Interactive Hit Test" script -> Select "Off" option for the script.
Most of the answers are correct but kind of obsolete, the correct way to do that is by code.
Create for example a gameObject called GameManager and pass the GroundPlaneStage and a prefab of the object you want to spawn to a script attached to that GameManager for example call it GameManagerScript.cs, and create a small function called spawnObjects which does the following:
public class SceneManagerScript : MonoBehaviour {
public GameObject objPrefab;
public GameObject ground;
private int count = 0;
public void spawnObject() {
Instantiate(objPrefab, new Vector3(count, 0, 0), Quaternion.identity, ground.transform);
count += 2;
}
}
then after that go to the PlaneFinder specifically to the PlaneFinderBehaviour.cs component you will have callbacks for OnInteractiveHitTest and OnAutomaticHitTest, in your case you need the OnAutomativeHitTest, click + and add a new callback (the function spawnObject in code above like in the image below)
also when you instantiate the object of your preference via the prefab don't forget to write the proper position updates to prevent the objects from getting added in the same position
also don't forget to make the GroundPlaneStage the parent of the object and realize that the position you are adding in the Instantiate() function is relative to that parent (GroundPlaneStage which is represented in the code above with the variable ground)
Finally don't forget to uncheck Duplicate Stage from the "Content Positioning Behaviour" component in the Plane Finder as shown in the picture below:
I hope that helps
please try the vuforia website for this problem
Introduction to Ground Plane in Unity
I have a scene that contains mutiple objects. How can i import it in xna and mentain each objects position? right now i export the scene in .fbx and load it in a model like this :
cube.model = contentManager.Load<Model>("cub");
but the objects don't retain their position and are all gathered in one point.
I need a method to import all the objects as individual objects but to retain the objects position in the scene?
(i.e. i need to import the scene so that i may manipulate the objects and retain their position in the scene so that i shouldn't reposition all the objects by myself)
Each object's scene position is in the fbx. The way to get it and implement it is to create a matrix array to hold every object's transform relative to the scene origin, then utilize the appropriate transforms when setting the effect.World for each object during draw time.
//class variables
Matrix[] objectTransforms;
//LoadContent section
cube.model = contentManager.Load<Model>("cub");
objectTransforms = new Matrix[cube.model.Bones.Count];
cube.model.CopyAbsoluteTransformsTo(objectTransforms);// the magic is done here
//draw method
foreach(ModelMesh mm in cube.model.Meshes)
{
foreach (BasicEffect bfx in mm.Effects)
{
bfx.World = objectTransforms[mm.ParentBone.Index] * whateverLocalTransformYouWant;
//draw here
}
}
Without utilizing 'objectTransforms' all objects will be drawn with their local origins located at the world origin, which sounds like what you are experiencing.
I personally made a level editor for most of the things in my game, but I do have a large scene in blender that links to other models. That way I can arrange all the level pieces in blender. When I export each individual piece, it does retain is global position and import correctly in the game. I would say that the issue resides in your fbx exporter. There should be an option to preserve location.
What modelling program do you use? If you use blender, there is an fbx exporter set made specifically for XNA that you should use.