Loading a 3D Model outside the XNA Game class - c#

I'm embedding my XNA Game inside a winforms' control. Because of this, I need to subclass Control, not Game.
How can I still load models from my content Project?
This is my code as I have it:
namespace KinectGraphics.XNAEmbedding {
class XNARenderControl : GraphicsDeviceControl {
Game selfGame;
public XNARenderControl() {
selfGame = new Game();
}
protected void LoadContent() {
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
model = selfGame.Content.Load<Model>("Ka-60");
//model = Content.Load<Model>("earth");
//model = Content.Load<Model>("3dm-tie-f-gt");
}
However, when execution reaches the selfGame.Content.Load, it throws ContentLoadException: Error loading "Ka-60". File not found.
What can I do to load the model anyway?

You haven't added the Root directory. You need to specify the full path to the model.

Related

instantiated object stays on screen after target image disappears

I am new to unity, I created an AR app following a YouTube tutorial that makes use of the Google/Apple native AR libraries and ARKit. I successfully built the app and deployed it to my iPhone. problem is, even when the target image leaves the screen, the instantiated object doesn't disappear. the script I copied is below, I don't know if that is where the problem is as I haven't learned scripting yet.
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
[RequireComponent(typeof(ARTrackedImageManager))]
public class PlaceTrackedImages : MonoBehaviour {
// Reference to AR tracked image manager component
private ARTrackedImageManager _trackedImagesManager;
// List of prefabs to instantiate - these should be named the same
// as their corresponding 2D images in the reference image library
public GameObject[] ArPrefabs;
// Keep dictionary array of created prefabs
private readonly Dictionary<string, GameObject> _instantiatedPrefabs = new Dictionary<string, GameObject>();
void Awake() {
// Cache a reference to the Tracked Image Manager component
_trackedImagesManager = GetComponent<ARTrackedImageManager>();
}
void OnEnable() {
// Attach event handler when tracked images change
_trackedImagesManager.trackedImagesChanged += OnTrackedImagesChanged;
}
void OnDisable() {
// Remove event handler
_trackedImagesManager.trackedImagesChanged -= OnTrackedImagesChanged;
}
// Event Handler
private void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs) {
// Loop through all new tracked images that have been detected
foreach (var trackedImage in eventArgs.added) {
// Get the name of the reference image
var imageName = trackedImage.referenceImage.name;
// Now loop over the array of prefabs
foreach (var curPrefab in ArPrefabs) {
// Check whether this prefab matches the tracked image name, and that
// the prefab hasn't already been created
if (string.Compare(curPrefab.name, imageName, StringComparison.OrdinalIgnoreCase) == 0
&& !_instantiatedPrefabs.ContainsKey(imageName)) {
// Instantiate the prefab, parenting it to the ARTrackedImage
var newPrefab = Instantiate(curPrefab, trackedImage.transform);
// Add the created prefab to our array
_instantiatedPrefabs[imageName] = newPrefab;
}
}
}
// For all prefabs that have been created so far, set them active or not depending
// on whether their corresponding image is currently being tracked
foreach (var trackedImage in eventArgs.updated) {
_instantiatedPrefabs[trackedImage.referenceImage.name]
.SetActive(trackedImage.trackingState == TrackingState.Tracking);
}
// If the AR subsystem has given up looking for a tracked image
foreach (var trackedImage in eventArgs.removed) {
// Destroy its prefab
Destroy(_instantiatedPrefabs[trackedImage.referenceImage.name]);
// Also remove the instance from our array
_instantiatedPrefabs.Remove(trackedImage.referenceImage.name);
// Or, simply set the prefab instance to inactive
//_instantiatedPrefabs[trackedImage.referenceImage.name].SetActive(false);
}
}
}
I used the script as is. I also created the exact same app using the vuforia plug in, found the setting in it to make the instantiated object dissappear. app worked perfect on my Mac, but when I deployed it to my iPhone all I get is a black screen. so out of 2 different builds I'm still stuck. would prefer an answer to the first scenario, but also curious about the second. I am using unity 2022.1.13 in both instances, can anyone please help?

How to remove 3dModel from Viewport [HelixToolKit WPF]

I am trying to create a question game with 3d models involved. I want my app to change the 3d model if the question is right. To do that I added a function called setupQ
Here is the code for it:
// To Setup Next 3dModel
public void SetupQ(string ModelS)
{
// SET 3d Model
ModelVisual3D device3D = new ModelVisual3D();
device3D.Content = Display3d(ModelS);
// Add to view port
viewPort3d.Children.Add(device3D);
}
Display3D Function:
private Model3D Display3d(string model)
{
Model3D device = null;
try
{
//Adding a gesture here
viewPort3d.RotateGesture = new MouseGesture(MouseAction.LeftClick);
//Import 3D model file
ModelImporter import = new ModelImporter();
//Load the 3D model file
device = import.Load(model);
}
catch (Exception e)
{
// Handle exception in case can not file 3D model
MessageBox.Show("Exception Error : " + e.StackTrace);
}
return device;
}
ModelS is the path to the 3d model. [The path does work].
How can I remove the 3d model that I just added and then add a new 3d model instead?
Is there a replace or clear function for the HelixToolKit?
Well I just figured the answer myself, it was quite simple.
To Clear the viewport you can:
viewPort3d.Children.Clear();
This will remove all lights, so you might as well want to add those back.
viewPort3d.Children.Add(new DefaultLights());
You can use:
viewPort3d.Children.Remove(yourModel);

Monogame - Issue with Loading between levels

As I'm currently making a 2D game, I'm trying to make it possible for my character to load between levels but I'm having a bit of an issue. The first level that my player starts on is loaded in an array with no issue at all in the Game1 class like this:
secondLevel secondLev; // instance for secondLevel class
Map map; // instance for Map class
secondLev = new secondLevel(); // used in the Initialize() function
protected override void LoadContent()
{
map.Generate(new int[,] {
// 0 = no tile drawn
// 3 = tile is drawn
{0,0,0,0,0,0,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,},
{3,3,3,3,3,3,3,3,3,3,},
{3,3,3,3,3,3,3,3,3,3,},
}, 57); // size
}
So to be able to load the second level, I have attempted to make a new class called secondLevel that holds the new level array and simply loads the array in its Load() function, like so:
class secondLevel
{
Map map;
public void Initialize()
{
map = new Map();
}
public void Load()
{
map.Generate(new int[,] {
// 0 = no tile drawn
// 3 = tile is drawn
{0,0,0,0,0,0,0,0,0,0,},
{0,0,0,0,0,0,0,0,0,0,},
{3,3,3,3,3,3,3,3,3,3,},
{3,3,3,3,3,3,3,3,3,3,},
{3,3,3,3,3,3,3,3,3,3,},
{3,3,3,3,3,3,3,3,3,3,},
}, 57); // size
}
}
Now in my Game1 class, I have placed an if statement that checks if the player has collided with the spike that loads the next level, like so:
if (player.Bounds.Intersects(spike1.Bounds)) // if player intersects with spike
{
secondLev.Load();
}
But when my player intersects with the spike, my game freezes and I get the error message: Object reference not set to an instance of an object.
What is my issue?
If I'm missing any additional code to my question that could help you fix this, please let me know!
Due to lack of context, it is hard to tell what exactly caused it. However, if the exception were to happen within the code that you presented, one of the following might be not be initialized : secondLev or secondLev.map.
if (player.Bounds.Intersects(spike1.Bounds)) // if player intersects with spike
{
secondLev = new secondLevel();
secondLev.Initialize();
secondLev.Load();
}
If that doesn't solve the problem, you should look at the stacktrace for clue.
Your secondLevel class is missing a constructor. That means that the Load() and Initialize() methods are never called. To fix this error, add a constructor that calls those methods.
Example:
public secondLevel(){
this.Initialize();
this.Load();
}
Another thing: you shouldn't be making a whole new class for each new level. Instead, you should have a Level struct (or class if you really want) that has all the properties of a Level. Then, to make new levels, just do Level secondLevel = new Level(map,size);

VS2012, C#, Monogame - load asset exception

I've been fighting with this problems for days now, browsing through the net, yet nothing helped me solve it: I'm creating a MonoGame application on Visual Studio 2012, yet when trying to load a texture I get the following problem:
Could not load Menu/btnPlay asset!
I have set content directory: Content.RootDirectory = "Assets"; Also the file btnPlay.png has properties set: Build Action: Content and Copy to Output directory: Copy if newer.
My constructor and LoadContent functions are totally empty, but have a look yourself:
public WizardGame()
{
Window.Title = "Just another Wizard game";
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Assets";
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
_spriteBatch = new SpriteBatch(GraphicsDevice);
Texture2D texture = Content.Load<Texture2D>("Menu/btnPlay");
_graphics.IsFullScreen = true;
_graphics.ApplyChanges();
}
I would be glad for any help! I'm totally desperate about the problem....
Under VS2012, Windows 8 64-bits and latest MonoGame as of today (3.0.1) :
create a subfolder named Assets
set Copy to Output to anything else than Do not copy
prepend assets to your texture path when loading it
namespace GameName2
{
public class Game1 : Game
{
private Texture2D _texture2D;
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
_texture2D = Content.Load<Texture2D>("assets/snap0009");
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(_texture2D, Vector2.Zero, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Here's your texture drawn :D
Note:
By convenience I kept the original value that the content's root directory points to : Content.
However, you can also directly specify Assets in the path:
Content.RootDirectory = #"Content\Assets";
Then load your texture without prepending Assets to its path:
_texture2D = Content.Load<Texture2D>("snap0009");

XNA - File Not Found

Can't find the answer anywhere, hoping you guys can help, thanks in advanced.
These were loaded in the beginning of the file-
SpriteBatch mBatch;
Texture2D mTheQuantumBros2;
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
mBatch = new SpriteBatch(this.graphics.GraphicsDevice);
//Create the Content Manager object to load images
ContentManager aLoader = new ContentManager(this.Services);
//Use the Content Manager to load the Cat Creature image into the Texture2D object
mTheQuantumBros2 = aLoader.Load<Texture2D>("TheQuantumBros2") as Texture2D;
// TODO: use this.Content to load your game content here
}
Error is saying the file is not found. File is TheQuantumBros2.png and I tried loading under the original game area and the content area. Neither is working and I put them in the directory and loaded them into the game on Visual Studio also. Ideas?
A few things could be happening...
Firstly, I see that you are are trying to make a new ContentManager. In my experience it is a lot easier to use the manager that is "built-in". Usually, it is either called 'contentManager', or 'Content' and is created when the class 'game1.cs' is generated. In general, it is best to simply use one content manager.
This is the correct content manager to use. In the constructor for "Game1.cs" it should say Content.RootDirectory = "Content". This tells the manager where the file is located. In your code, that is what you are missing. It simply does not know where to look for the file.
So add this to your code:
SpriteBatch mBatch;
Texture2D mTheQuantumBros2;
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
mBatch = new SpriteBatch(this.graphics.GraphicsDevice);
//Create the Content Manager object to load images
ContentManager aLoader = new ContentManager(this.Services);
//ADD THIS
aLoader.RootDirectory = "Content";
//Use the Content Manager to load the Cat Creature image into the Texture2D object
mTheQuantumBros2 = aLoader.Load<Texture2D>("TheQuantumBros2") as Texture2D;
// TODO: use this.Content to load your game content here
}

Categories