Create an animation from obj/gtlf files, import in Unity - unity3d

I have 350 gtlf files. Originally files are in OBJ format (350 files + audio) and I have converted them into separate gtlf with obj2gtlf.
How can I create an animated gtlf file with all 350 keyframes? Or how can I create an animation in Unity using these 350 obj/gltf files?
I want to import/create a animation in Unity using these files and run a Hololens Application. By placing this animation I want to see a volumetric video playing inside my Hololens Application.
But I can not make a sequence using a gtlf-transform, it seems to take only one gtlf file (instead of all 350) and detach the texture into separate jpg-file. I can not create animation with Timeline in Unity.
Can anyone help me? I am new to Unity and can not find a solution
PS: Bone animation is not a solution. My files are represent a real man that is captured with a volumetric video method. He stays, speaks, smiles and moves his hand. I need to import a 3d animated model into Unity to use it my master thesis. So I did not animated that model, I have got a captured video as 350 obj files + meshes as jpg and audio. I can import a single 3d model as obj file but I can not find a way to import a animated volumetric video.

You seem to have a very specific use case where indeed you need to have these as separate 3D models and textures / materials.
As said the simplest but probably not most performant way would be to simply have all these 3D objects in your scene and only set one of them active at a time.
Something like e.g.
public class ModelFrames : MonoBehaviour
{
// You drag these all in once via the Inspector
public GameObject[] models;
private int currentIndex = -1;
private void Awake()
{
foreach(var model in models)
{
model.SetActive(false);
}
}
private void Update()
{
if(currentIndex >= 0)
{
models[currentIndex].SetActive(false);
}
currentIndex = (currentIndex + 1) % models.Length;
models[currentIndex].SetActive(true);
}
}
If you don't want to switch every frame you could also add some modifier and do
public class ModelFrames : MonoBehaviour
{
// You drag these all in once via the Inspector
public GameObject[] models;
public int targetFramesPerSecond = 60;
private void Awake()
{
foreach(var model in models)
{
model.SetActive(false);
}
}
private IEnumerator Start()
{
var currentIndex = 0;
models[currentIndex].SetActive(true);
while(true)
{
yield return new WaitForSeconds(1f / targetFramesPerSecond);
models[currentIndex].SetActive(false);
currentIndex = (currentIndex + 1) % models.Length;
models[currentIndex].SetActive(true);
}
}
}

Related

How do i get the the tile in front of the player in unity 2d

I'm trying to get all tiles around the player in unity 2d tileset.
What I would like to happen when player presses U I Would like to get all tiles surrounding the player including the one underneath the player or simply the one 1 tile in front of them.
I'm trying to make a farming Game where when the player pulls out an item it will highlight on the tilemap where they are about to place it.
Please note I'm not asking for full code, I just want what ever solution allows me to get tiles near the players position
Edit, found a solution by editing someone elses code but im not sure if there's a better way, if not I would also like this to work based on player rotation currently it places a tile above the player. Code Source https://lukashermann.dev/writing/unity-highlight-tile-in-tilemap-on-mousever/
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Tilemaps;
public class PlayerGrid : MonoBehaviour
{
private Grid grid;
[SerializeField] private Tilemap interactiveMap = null;
[SerializeField] private Tilemap pathMap = null;
[SerializeField] private Tile hoverTile = null;
[SerializeField] private Tile pathTile = null;
public GameObject player;
private Vector3Int previousMousePos = new Vector3Int();
// Start is called before the first frame update
void Start()
{
grid = gameObject.GetComponent<Grid>();
}
// Update is called once per frame
void Update()
{
var px = Mathf.RoundToInt(player.transform.position.x);
var py = Mathf.RoundToInt(player.transform.position.y);
var tilePos = new Vector3Int(px, py, 0);
if (!tilePos.Equals(previousMousePos))
{
interactiveMap.SetTile(previousMousePos, null); // Remove old hoverTile
interactiveMap.SetTile(tilePos, hoverTile);
previousMousePos = tilePos;
}
// Left mouse click -> add path tile
if (Input.GetMouseButton(0))
{
pathMap.SetTile(tilePos, pathTile);
}
// Right mouse click -> remove path tile
if (Input.GetMouseButton(1))
{
pathMap.SetTile(tilePos, null);
}
}
}
try to use the layer field inside the inspector, you can create new Layers inside the Project Manager and there you can easily create Layers like "Background" "Scenery" "Player" "Foreground".. after this you can assign them individually to your Tiles also its important to have different grids otherwise you will not be able to assign different layers to it i hope it worked already

Can you export sliced sprites (PNG images) in Unity?

So I have a Sprite 2d and UI in unity. (Png image) That contains many small images like buttons. So I slice them and I can use them individualy in unity. But the thing is that I want to export each of the png Images that I got while slicing them for another use. So can I do that? And have them as separate pngs?
And what I want is these Images:
To export them in my (lets say) desktop as individual pngs.
Thank you!
I had a need for this too, I ended up solving it with a simple editor script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class ExportSubSprites : Editor {
[MenuItem("Assets/Export Sub-Sprites")]
public static void DoExportSubSprites() {
var folder = EditorUtility.OpenFolderPanel("Export subsprites into what folder?", "", "");
foreach (var obj in Selection.objects) {
var sprite = obj as Sprite;
if (sprite == null) continue;
var extracted = ExtractAndName(sprite);
SaveSubSprite(extracted, folder);
}
}
[MenuItem("Assets/Export Sub-Sprites", true)]
private static bool CanExportSubSprites()
{
return Selection.activeObject is Sprite;
}
// Since a sprite may exist anywhere on a tex2d, this will crop out the sprite's claimed region and return a new, cropped, tex2d.
private static Texture2D ExtractAndName(Sprite sprite) {
var output = new Texture2D((int)sprite.rect.width, (int)sprite.rect.height);
var r = sprite.textureRect;
var pixels = sprite.texture.GetPixels((int)r.x, (int)r.y, (int)r.width, (int)r.height);
output.SetPixels(pixels);
output.Apply();
output.name = sprite.texture.name + " " + sprite.name;
return output;
}
private static void SaveSubSprite(Texture2D tex, string saveToDirectory) {
if (!System.IO.Directory.Exists(saveToDirectory)) System.IO.Directory.CreateDirectory(saveToDirectory);
System.IO.File.WriteAllBytes(System.IO.Path.Combine(saveToDirectory, tex.name + ".png"), tex.EncodeToPNG());
}
}
First, drop this into a script file named EditorSubSprites.cs and make sure that it resides in an Editor folder. If you have no editor folder you can simply create at /Assets/Editor/
To use, expand a texture asset's sprites, and select as many of the sprites as you wish to export. Right-click and select "Export SubSprites".
Use Photoshop, Crop it, a Lot of Cut and Paste is going to happen save as PNG.
Import it to unity inside the folder, i like your designs. Also Watch Brackeys Tutorial on Youtube, https://www.youtube.com/user/Brackeys , he save me from my school years.
(edit : i recommend Photoshop because its the only thing i know.)

Unity3D: Setting AudioSource volume dynamically using AnimationCurve

Newcomer to Unity here. For this project, I am reading in an outside AnimationCurve, and attempting to use it to adjust the volume of my GameObject every frame in the Update function. I have found documentation on how to access the volume of my AudioSource GameObject component (this is working), but I can't figure out how to use my evaluated curve to update the volume.
Screencap with imported AnimationCurve and evaluated values
My cs script is included below. Sorry if it's a bit opaque. This is for a neuroscience experiment, so I need to carefully control the animation curves. It reads in times and values (stored in currentCurveData) used to add keyframes to the new AnimationCurve (curveThisTrl) in the SetAnimationFrames() function.
The key part is in Update(). The initial tone.volume is correct, so I know it's reading that property from the GameObject. I can also see the correct curve values coming through in the Debug Log every frame, so I know the curve evaluation is working. It's just not changing the volume property of the GameObject as I want it to.
Hopefully this is enough information to spot a problem, but if not I can try to provide a test AnimationCurve for reproducibility. Thanks in advance for any help.
public class AnimationControl : MonoBehaviour {
private DataController dataControllerRef;
private CurveDataSingleTrial currentCurveData;
private float initTime;
public AnimationCurve curveThisTrl;
AudioSource tone;
void Awake()
{
initTime = Time.time;
}
// Use this for initialization
void Start ()
{
// Get references to key objects in scene
dataControllerRef = FindObjectOfType<DataController>(); // Has values from JSON
tone = GetComponent<AudioSource>();
Debug.Log(tone.volume);
// query the DataController for the current curve data
currentCurveData = dataControllerRef.GetCurrentCurveData();
SetAnimationFrames();
}
void SetAnimationFrames()
{
int numKeyFrames = currentCurveData.keyframeTimes.Length;
for (int c = 0; c < numKeyFrames; c++)
{
curveThisTrl.AddKey(currentCurveData.keyframeTimes[c], currentCurveData.keyframeVals[c]);
}
}
// Update is called once per frame
void Update ()
{
float currTime = Time.time - initTime;
tone.volume = curveThisTrl.Evaluate(currTime);
Debug.Log(tone.volume);
}
}

Issue with playing background audio for different scenes in unity3d

In my game, I have two scene.
What I want to achieve is if user navigates from one scene to another, background audio specific to each should be played from start(audio length=0)
But all my efforts are in vain.
I tried using 'Pause' Method of audioSound
I tried
create a new game object and assign this scene background score to it and play
destroy gameObject created for another scene if there was any
But it doesn't give the result that I want.
I searched for finding how to play audioClip from start and stop other audioClip playing but didn't find any.
I know I'm not supposed to ask for code on stack overflow but if anyone has achieved this or has some pseudo code request you to provide it
I'm not sure I understand your question properly, since it seems the simplest scenario for background music.
If you really want a change of audioclip in every scene, let's say Scene A must play Clip A and Scene B must play Clip B, and both clips should be played as soon as a scene is loaded, you just need to create a game object in both scenes with an Audio Source component, with the Play On Awake flag active, and then just assign the appropriate clip for the scene (i.e.: assign Clip A in the Audio Clip field of the Audio Source component of Scene A game object, and do the same with Clip B for Scene B).
That's pretty much it.
If you looking at the detail code then you can try this code.
First : Make a script "SoundFxScript.cs" // You can modified as you want
Insert this code :
public class SoundFxScript : MonoBehaviour {
//Background Music
public AudioSource Scene1_Sound;
public AudioSource Scene2_Sound;
// Use this for initialization
void Start () {
PlayBackgroundMusic ();
}
// Update is called once per frame
void Update () {
}
public void PlayBackgroundMusic() {
if (UnityEngine.SceneManagement.SceneManager.GetActiveScene ().name == "Scene1") {
Scene1_SoundPlay();
} else if (UnityEngine.SceneManagement.SceneManager.GetActiveScene ().name == "Scene2") {
Scene2_SoundPlay();
}
}
public void Scene1_SoundPlay() {
Scene1_Sound.Play ();
Scene2_Sound.Stop ();
}
public void Scene2_SoundPlay() {
Scene1_Sound.Stop ();
Scene2_Sound.Play ();
}
// Step Fifth
public void LoadTheScene (string Scenename) {
UnityEngine.SceneManagement.SceneManager.LoadScene (Scenename);
sf.PlayBackgroundMusic ();
}
}
Second : Make Gameobject name = "SoundMusic" at the first scene and add component script SoundFxScript.cs. In gameobject "SoundMusic" you can add you background music for scene1 and scene2.
Third : Make a singleton file Singleton.cs
Insert this code :
public class Singleton : MonoBehaviour {
static Singleton instance = null;
void Start ()
{
if (instance != null)
{
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
instance = this;
}
}
Fourth : at gameobject "SoundMusic" add component script "Singleton.cs"
Fifth : How To Call In Another Scene (Load Scene). This method is inside SoundFxScript.cs
Example You have a method to call a load scene. Try this method :
Call it with : LoadTheScene("Scene2") // Call scene2
In here you can call your SoundFxscript.cs Component from any script you have.
Example :
SoundFxScript sf;
sf = GameObject.Find ("SoundMusic").GetComponent<SoundFxScript> ();
And you can use method LoadTheScene to load a new scene and the background music will RePlay again according to the what Scene is it.
That's All.

how to randomly initialize particles system in different places of scene in unity3d

I recently tried asking this question but I realized it was not a sufficient question. In my game the player is a fire fighter learner and i want to broke out fire randomly in my game (like not predictable by player), but i did not know how to implement this.
So far i have done this but nothing goes good.(I have a empty object called t in unity which have 3 to 5 particles systems, and all are set to dont awake at start)
code is here :
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
public ParticleSystem[] particles;
public int numOn = 3;
public int j;
void Start() {
for (int i = 0; i < particles.Length - 1; i++) {
j = Random.Range(i + 1, particles.Length - 1);
ParticleSystem t = particles[j];
particles[j] = particles[i];
particles[i] = t;
}
for (j = 0; j < numOn; j++ )
{
particles[j].Play();
}
}
}
help will be appreciated :-)
You could try using prefabs. Create a game object in the editor that has any particle systems and scripts your fire objects need. Once it's good, drag the object from the hierarchy into your project. This will create a prefab (you can now remove it from the scene). Now, on your spawning script, add a field of type GameObject and drag the prefab you made before into it. Now, when you need to create one, just call Instantiate(prefabVar) to create a copy of your prefab.
Edit:
For your specific case, since you only want one fire to be instantiated in a random location, you could have your spawning script look something like this:
public Transform[] SpawnPoints;
public GameObject FirePrefab;
void Start() {
Transform selectedSpawnPoint = SpawnPoints[(int)Random.Range(0, SpawnPoints.Count - 1)];
Instantiate(FirePrefab, selectedSpawnPoint.position, selectedSpawnPoint.rotation);
}
This solution would allow for you to potentially spawn more than one fire object if you needed. An alternative would be if you will only ever have exactly one fire object in the scene at all. Instead of instantiating from a prefab, the object is already in the scene and you just move it to one of your spawn points at the start of the scene. An example script on the fire object itself:
public Transform[] SpawnPoints;
void Start() {
Transform selectedSpawnPoint = SpawnPoints[(int)Random.Range(0, SpawnPoints.Count - 1)];
transform.position = selectedSpawnPoint.position;
transform.rotation = selectedSpawnPoint.rotation;
}