Spawn an object on Spatial Mapping Mesh with Hololens 2 - c#

I am currently working with the Hololens 2 for a project and am now trying to spawn an object at the position I target with the hand ray. First I created a mesh with the Spatial Awareness System from MRTK and now I want to spawn an object at the position of the cursor.
I read about a lot of ways I can handle this, like cursor.transform.position (which doesn't work, maybe because I use the default cursor?) and Instantiate, the component "Tap to Place", or using RaycastHit. Unfortunately, because this is my first time working with the Hololens, I don't know which solution might be the best. I don't think it can be that hard to spawn something, but maybe I am just blind.
Is there an easy way to solve my problem or get the right coordinates from the cursor of the hand gaze?

Here you go, use IMixedRealityPointerHandler. See the documentation.
public void OnPointerClicked(MixedRealityPointerEventData eventData)
{
var result = eventData.Pointer.Result;
var hitPosition = result.Details.Point;
// Check if hitting spatial mapping layer
if (result.CurrentPointerTarget?.layer == 31)
Instantiate(yourPrefab, hitPosition, yourRotation);
else
Debug.Log("Hit surface with layer: " + result.CurrentPointerTarget?.layer.ToString());
}

Related

Unity 3D - Moving Object & Player with Push/Pull || Applying Opposing Force

so I've been struggling with a problem for a while, not sure how to approach it.
I'm trying to simulate a magic system similar to The Force used in Star Wars in Unity, and have ran into some troubles. I'm trying to simulate pushing and pulling on objects appropriately. This means that when the player pushes an object, both the player and the object get a force applied to them. If the object is light enough, the player shouldn't be affected in any noticeable way, and the object should be pushed away. If their masses are similar, both should be pushed away at some rate, and if the object is heaver, the player should be mainly pushed away. The same goes with pulling. The problem is when objects are anchored against something. If a player pushes a light object into a wall, the player should start receiving enough force to start pushing them backwards, since the combined mass of the wall and the object are pushing the player back.
Currently, I'm able to do the first part with the following code when a key is pressed:
Note that the force is determined based off the distance from the player to the object and the mass of them.
// dir: push or pull (-1 or 1)
Vector3 directionToPlayer = (dir * (player.transform.position - transform.position)).normalized;
rb.AddRelativeForce(directionToPlayer * f * Time.deltaTime);
player.GetComponent<Rigidbody>().AddRelativeForce(-directionToPlayer * f * Time.deltaTime);
As it is, the code works fine when the objects are just by themselves just by relying on Unity's Physics system. However, it does NOT work when an object is being pushed against a wall, or something really heavy. This is pretty clear as I'm just applying the same force to both the object and the player, and letting Unity decide whether to move the entity based off its rigidbody mass.
My question is, how can I detect if an object is anchored, and if it is combine the mass of the object and the object which it is anchored to, and apply that force to the player? I was thinking how to do this, and I know that I need to figure out the direction of which the force is being applied from, and then determine whether the object that's being pushed or pulled is colliding with anything in that direction, and if so apply a force to the player based off the combined masses. This gets a little tricky however when pushing an object at an angle that's against a wall. For example consider the following scenario:
There is both a horizontal and a vertical component of the force being applied on the cube, and so that should be considered when the cube+wall combined object pushes back on the player. How could this be accomplished or approached? I'm really struggling coming up with how to do this without hard coding direcitons.
Any help is appreciated, and I'll gladly clarify if anything is unclear.
NOTE The system is really based from a book series called Mistborn, but the concept is really close to The Force in Star Wars, and so I'll run with that as more people are familiar with it
This is not a complete solution, but you can use my idea below to acquire the nearby objects and then apply force to your objects and player in accordance with that.
The script should be placed on the object you are pushing or at least use a sphere collider from the object you are pushing.
public List<string> _ValidTargetTags = new List<string> { "Wall" };
public void CheckNearbyArea()
{
//Each of the nearby items will be checked to see if they are a wall or other valid target.
Collider[] ObjectsStruck = ScanForItems(GetComponent<SphereCollider>());
foreach (var o in ObjectsStruck)
{
if (_ValidTargetTags.Contains(o.gameObject.tag))
{
//If wall or other valid target
//Check where wall is placed
//Act according to wall position.
}
}
}
///The method below should find a list of all items inside a spherecollider of the object you are pushing.
Collider[] ScanForItems(SphereCollider sphereCollider)
{
Vector3 center = sphereCollider.transform.position + sphereCollider.center;
float radius = sphereCollider.radius;
Collider[] allOverlappingColliders = Physics.OverlapSphere(center, radius);
return allOverlappingColliders;
}
With this solution you will be able to check the players location relative to any nearby walls. This you can use to calculate what his direction is compared to the wall, relative to the object he is pushing.

Unity 3D: How can I have directional light on for one camera and off for another?

I need to show two camera display side by side. One will have the sun(directional light) on and one will have the sun off while rendering the same scene at the same time. I have tried to use sun.SetActive() inside of OnPreRender() method, for one Camera I set it sun.SetActive(false) and sun.SetActive(true) for another. It does not work, sun remains off for both camera. How can I achieve the desired output?
You need to add OnPreCull too to your initial try for versions highers than Unity 4.6.
I preserve OnPrerender for older versions, you got an advice on your log but ignore it.
Add this script to your camera:
function OnPreCull () {
if (sun != null)
sun.enabled = false;
}
function OnPreRender() {
if (sun != null)
sun.enabled = false;
}
function OnPostRender() {
if (sun != null)
sun.enabled = true;
}
Another way to do this would be to have all gameobjects duplicated and set to different layers - e.g.: 'Sunlit' and 'Shadowed'. The duplicate object needs to be nested within the original object, which can be quite messy, you'd need a script to duplicate the scene's objects at runtime.
The hierarchy would look something like this:
Your directional light's culling mask (on the light's inspector) would be set to everything but to the objects on the 'Shadowed' layer.
Then 2 cameras, culling everything but one of the layers:
I'm unsure if this is better or worse than joreldraw's solution in terms of performance. But I would guess it would depend on the amount and complexity of the models. On joreldraw's solution we're enabling/disabling the lightsource several times per frame. With this solution we have twice the gameobjects. If you don't have a lot of objects on your scene, then perhaps this solution is better.

Unity3d maintaining a minimum distance between multiple GameObjects c#

I have multiple enemies that move toward the player. I am trying to stop them from merging into each other, i.e maintain some type of minimum distance between each other. What I'm trying is this (from unity3d forums):
enemy1.transform.position = (enemy1.transform.position -
enemy2.transform.position).normalized * distance + enemy2.transform.position;
However, when I have >= 3 enemies they still seem to bunch up even when I apply this to every enemy combination.
I need a better method as this one does not work and does not scale.
What you do around your enemy prefab is place a quad box which in effect is a trigger element, then on you script for the enemy you set that if another enemy (using tag types, I imagine) comes within touching of the quad box then to run appropriate code to stop the enemy getting closer in and to prevent the enemy actually overlapping with this trigger box.
Your code you example in your question looks like it is referencing the enemy units specifically rather than as instance entitites which is very probably a bad way of coding, as you're finding, it's very inflexible dealing with not-specifically-named reference entities.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
private Transform otherEntity;
public float distance = 50.0f;
private Transform thisEntity;
void OnTriggerEnter(Collider other)
{
otherEntity = other.GetComponent<Transform>();
thisEntity = GetComponent<Transform>();
thisEntity.position = (thisEntity.position - otherEntity.position).normalized * distance + otherEntity.position;
}
}
I have not tested the above code but using the code you reference the values for the transform are loaded from the Game Component for the referenced entities, as this has changed ALOT in Unity since release of version 5.1 and your source for your code was an answer given in 2012!!
thisEntity is the object that the script is attached to, typically one of the enemy. The otherEntity is the object that comes within the quad trigger (please remember the quad needs to be referenced as a trigger element.
The values of the Entity variables need to be set once the trigger is entered, so that it always effects the correct other element.
(I may be totally wrong with my methodology but I hope this helps.)

Rotating a unity configurable joint to match another game object (copycat)

I'm trying to drive a configurable joint to the same rotation as another game object. Basically I'm trying to get one marionette to shadow another.
Im using the following code:
public GameObject master;
public GameObject slave;
void Update (){
ConfigurableJoint cj = slave.transform.GetComponent(typeof(ConfigurableJoint)) as ConfigurableJoint;
cj.targetRotation = master.transform.rotation;
}
However, I don't get any rotation out of the slave. Can anyone explain what I should be doing?
Are you sure you are getting the right joint ? Is cj null ?
Maybe try this line instead :
ConfigurableJoint cj = slave.GetComponent<ConfigurableJoint>();
When you are dealing with physics you can't apply rotation to a Rigid Body. What you can do is copy and paste the local transform to another non-static game object in relationship with its perent that does not contain a Rigid Body.
So basically the configurable joint has so so many options and parameters to set it up to your need that you need to take a course 2hrs course. There is no space here for a simple answer to set it up. I recommend this free old course because is the only one that at the moment explains in deep: This is more a general answer but works. There is an old tutorial in Unity3 that explains the setup:
https://archive.org/details/3dbuzz-archive/unity-fundamentals-part-04/020-physics/013-13-configurable-joint.mp4

Collisions between CharacterController and BoxCollider

I'm trying to detect collision between the characterController and a platform (a rigidBody + boxCollider) in an Unity project.
I know that I can use this function at the characterController object:
void OnControllerColliderHit(ControllerColliderHit hit) {
// [...];
}
But I would strongly rather to detect it in the platform object, in order to try to maintain the code clearer. Something like this:
void OnCollisionEnter(Collision c) {
Debug.Log(c.gameObject.tag);
}
But it is not working! I searched in Unity forums and apparently the only way to detect a collision is to set the boxCollider's property isTrigger as True and using .OnTriggerEnter(Collider c) method instead. However, doing it will cause the player to fall through the platform, which obviously can't happen.
Alright, so my question is: is there another way to do it - whithout setting isTrigger as True - and detecting the collision in the platform object?
Thank you!
The way I handled a similar problem with a platform and a character controller, is by adding a child object to the platform with a trigger collider set to a larger size than the platform itself (think of it like an invisible box surrounding your platform). What this does is allow you to know if your player is going to hit the platform, the direction he's coming from etc. Then it's a simple matter of sending a message to the platform, with an necessary information parentPlatformObject.SendMessage(params)
I would like to suggest something very similar to what Steven Mills suggested, but may make things easier in the long run.
Add a child object to the player, that has a trigger collision box the size of the player (or just around it's feet if that's what you care about), but has a specific layer only for itself. In the project physics settings, make said layer only interact with the platform's layer. This means you won't trigger if this box hits anything else except for the platforms (like the rest of the player). Since the non triggers had not changed, the player and the platform will behave as you expect (just as with Steven's solution) but if you add new types of objects that you wish to land on/hit, and want them to work in a similar manner, you will not need double the prefabs/make 2 objects, just 1 with the correct layer assigned.

Categories

Resources