How to set second material to a second submesh in a combined mesh? - unity3d

I have this code (not originally my invention) that is working fine, but I have hit upon a problem with it. I can't seem to render the second submesh, with another material.
I can't figure out the problem lies in [renderer] part or the 2nd "submesh" that is perhaps never combining.
#script RequireComponent(MeshFilter)
#script RequireComponent(MeshRenderer)
private var matarray : Material[] = new Material[2];
var mat : Material;
var mat2 : Material;
function Start () {
matarray[0] = mat;
matarray[1] = mat2;
for (var child in transform)
child.position += transform.position;
transform.position = Vector3.zero;
transform.rotation = Quaternion.identity;
var meshFilters = GetComponentsInChildren(MeshFilter);
var combine : CombineInstance[] = new CombineInstance[meshFilters.Length-1];
var index = 0;
for (var i = 0; i < meshFilters.Length; i++) {
if (meshFilters[i].sharedMesh == null)
continue;
combine[index].mesh = meshFilters[i].sharedMesh;
combine[index++].transform = meshFilters[i].transform.localToWorldMatrix;
renderer.sharedMaterials = matarray;
meshFilters[i].active = false;
}
GetComponent(MeshFilter).mesh = new Mesh();
GetComponent(MeshFilter).mesh.CombineMeshes(combine);
renderer.active = true;
//here seems to be the trouble.
renderer.sharedMaterials = matarray;
}
Alternatively I have tried,
renderer.sharedMaterials[1] = matarray[1];
In short, I'm in trouble. I have to save few draw calls, which is not looking good unless this gets fixed.

Related

Floating origin and visual effect graph in Unity

I am sure that everybody knows about this script, http://wiki.unity3d.com/index.php/Floating_Origin, that fixes problems with floating origin easily.
The problem is that the script is outdated and does not move the particle effects created by visual effect graph.
I was trying to rewrite it but I cant seem to make an array to store all the particles, like with the previous one, thus I can't continue from there.
Here is my code:
// Based on the Unity Wiki FloatingOrigin script by Peter Stirling
// URL: http://wiki.unity3d.com/index.php/Floating_Origin
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.VFX;
using UnityEngine.Experimental.VFX;
public class FloatingOrigin : MonoBehaviour
{
[Tooltip("Point of reference from which to check the distance to origin.")]
public Transform ReferenceObject = null;
[Tooltip("Distance from the origin the reference object must be in order to trigger an origin shift.")]
public float Threshold = 5000f;
[Header("Options")]
[Tooltip("When true, origin shifts are considered only from the horizontal distance to orign.")]
public bool Use2DDistance = false;
[Tooltip("When true, updates ALL open scenes. When false, updates only the active scene.")]
public bool UpdateAllScenes = true;
[Tooltip("Should ParticleSystems be moved with an origin shift.")]
public bool UpdateParticles = true;
[Tooltip("Should TrailRenderers be moved with an origin shift.")]
public bool UpdateTrailRenderers = true;
[Tooltip("Should LineRenderers be moved with an origin shift.")]
public bool UpdateLineRenderers = true;
private ParticleSystem.Particle[] parts = null;
VisualEffect[] visualEffect = null;
void LateUpdate()
{
if (ReferenceObject == null)
return;
Vector3 referencePosition = ReferenceObject.position;
if (Use2DDistance)
referencePosition.y = 0f;
if (referencePosition.magnitude > Threshold)
{
MoveRootTransforms(referencePosition);
if (UpdateParticles)
MoveParticles(referencePosition);
if (UpdateTrailRenderers)
MoveTrailRenderers(referencePosition);
if (UpdateLineRenderers)
MoveLineRenderers(referencePosition);
}
}
private void MoveRootTransforms(Vector3 offset)
{
if (UpdateAllScenes)
{
for (int z = 0; z < SceneManager.sceneCount; z++)
{
foreach (GameObject g in SceneManager.GetSceneAt(z).GetRootGameObjects())
g.transform.position -= offset;
}
}
else
{
foreach (GameObject g in SceneManager.GetActiveScene().GetRootGameObjects())
g.transform.position -= offset;
}
}
private void MoveTrailRenderers(Vector3 offset)
{
var trails = FindObjectsOfType<TrailRenderer>() as TrailRenderer[];
foreach (var trail in trails)
{
Vector3[] positions = new Vector3[trail.positionCount];
int positionCount = trail.GetPositions(positions);
for (int i = 0; i < positionCount; ++i)
positions[i] -= offset;
trail.SetPositions(positions);
}
}
private void MoveLineRenderers(Vector3 offset)
{
var lines = FindObjectsOfType<LineRenderer>() as LineRenderer[];
foreach (var line in lines)
{
Vector3[] positions = new Vector3[line.positionCount];
int positionCount = line.GetPositions(positions);
for (int i = 0; i < positionCount; ++i)
positions[i] -= offset;
line.SetPositions(positions);
}
}
private void MoveParticles(Vector3 offset)
{
var particles = FindObjectsOfType<ParticleSystem>() as ParticleSystem[];
foreach (ParticleSystem system in particles)
{
if (system.main.simulationSpace != ParticleSystemSimulationSpace.World)
continue;
int particlesNeeded = system.main.maxParticles;
if (particlesNeeded <= 0)
continue;
bool wasPaused = system.isPaused;
bool wasPlaying = system.isPlaying;
if (!wasPaused)
system.Pause();
// ensure a sufficiently large array in which to store the particles
if (parts == null || parts.Length < particlesNeeded)
{
parts = new ParticleSystem.Particle[particlesNeeded];
}
// now get the particles
int num = system.GetParticles(parts);
for (int i = 0; i < num; i++)
{
parts[i].position -= offset;
}
system.SetParticles(parts, num);
if (wasPlaying)
system.Play();
}
var particles2 = FindObjectsOfType<VisualEffect>() as VisualEffect[];
foreach (VisualEffect system in particles2)
{
int particlesNeeded = system.aliveParticleCount;
if (particlesNeeded <= 0)
continue;
bool wasPaused = !system.isActiveAndEnabled;
bool wasPlaying = system.isActiveAndEnabled;
if (!wasPaused)
system.Stop();
// ensure a sufficiently large array in which to store the particles
if (visualEffect == null || visualEffect.Length < particlesNeeded)
{
visualEffect = new VisualEffect().visualEffectAsset[particlesNeeded];
}
// now get the particles
int num = system.GetParticles(parts);
for (int i = 0; i < num; i++)
{
parts[i].position -= offset;
}
system.SetParticles(parts, num);
if (wasPlaying)
system.Play();
}
}
}
On the line(this is a wrong line and everything below it too)
visualEffect = new VisualEffect().visualEffectAsset[particlesNeeded];
, I need to create a similar array to the line (correct one, but for the old particle system)
parts = new ParticleSystem.Particle[particlesNeeded];
that creates array full of particles (but with VisualEffect class).
If I can fix this one, there should not be any problem with the rest.
I think that solving this problem will help literally thousands of people now and in the future, since limitation for floating origin in unity are horrible and majority of people working in unity will need floating origin for their game worlds, with VFX graph particles.
Thanks for the help.
My question has been answered here:
https://forum.unity.com/threads/floating-origin-and-visual-effect-graph.962646/#post-6270837

AddComponent("Rigidbody") or another component doesn't work

I am trying to program a very simple FPS game and I reached a point where I need to create a pickup weapon system. In order to finish that system, I am stuck on a point where I need to AddComponent("Rigidbody") and AddComponent("BoxCollider") and Unity3D throws that error:
'AddComponent is not a member of 'WeaponPickUp'
Where WeaponPickUp is my Javascript script file.
Below is my code:
#pragma strict
var pickup = false;
var check = 2;
function Update () {
if (Input.GetButtonDown("pickup") && check % 2 == 0){
GetObject();
pickup = true;
check = check + 1;
}
else if (Input.GetButtonDown("pickup") && (check % 2 == 1)){
pickup = false;
check = check - 1;
this.AddComponent("Rigidbody") as Rigidbody;
this.AddComponent("BoxCollider") as BoxCollider;
this.GetComponent(BoxCollider).enabled = true;
}
}
function GetObject(){
var position : GameObject = GameObject.Find("weaponPosition");
this.transform.position = position.transform.position;
Destroy(GetComponent(Rigidbody));
Destroy(GetComponent(BoxCollider));
this.transform.parent = GameObject.Find("FPSController").transform;
this.transform.parent = GameObject.Find("FirstPersonCharacter").transform;
// this.transform.parentposition
}
I've no idea why this happens. Anybody willing to help me out, I will appreciate it as always!
This
this.AddComponent("Rigidbody") as Rigidbody;
this.AddComponent("BoxCollider") as BoxCollider;
this.GetComponent(BoxCollider).enabled = true;
needs to be
gameObject.AddComponent("Rigidbody") as Rigidbody;
gameObject.AddComponent("BoxCollider") as BoxCollider;
gameObject.GetComponent(BoxCollider).enabled = true;
Same for the Destroy lines
AddComponent is part of GameObject, not your WeaponPickUp
Remove this keyword with gameObject then remove as Rigidbody and as BoxCollider
This is what it should look like:
gameObject.AddComponent("Rigidbody");
gameObject.AddComponent("BoxCollider");
gameObject.GetComponent("BoxCollider").enabled = true;
The syntax above should have worked but it is obsolete. It changed in Unity 5.
You will get error if you do it like that. Below is the new syntax and right way to do it now.
GetComponent.<Rigidbody>();
GetComponent.<BoxCollider>();
GetComponent.<BoxCollider>().enabled = true;
Your whole code:
#pragma strict
var pickup = false;
var check = 2;
function Update () {
if (Input.GetButtonDown("pickup") && check % 2 == 0){
GetObject();
pickup = true;
check = check + 1;
}
else if (Input.GetButtonDown("pickup") && (check % 2 == 1)){
pickup = false;
check = check - 1;
GetComponent.<Rigidbody>();
GetComponent.<BoxCollider>();
GetComponent.<BoxCollider>().enabled = true;
}
}
function GetObject(){
var position : GameObject = GameObject.Find("weaponPosition");
this.transform.position = position.transform.position;
Destroy(GetComponent(Rigidbody));
Destroy(GetComponent(BoxCollider));
this.transform.parent = GameObject.Find("FPSController").transform;
this.transform.parent = GameObject.Find("FirstPersonCharacter").transform;
// this.transform.parentposition
}

How to make a 15 sliding puzzle game?

I have created a game that has 16 spheres in it and they are swapping on mouse click. But I want to have 15 spheres and one empty gameobject, so as to make them slide with the help of an empty gameobject.and i also want to shuffle the spheres when game starts each time. How is it possible?
I follow this tutorial
After that I tried to make it, but my cubes get overlapped on one another while changing their position on start.
var xtemp ;
var ytemp ;
var slot : Transform;
var cubesPosition : Vector3[] = new Vector3[16];
var cubeGameObjects: GameObject[] = new GameObject[16];
function Start ()
{
ChangePosition();
AssignPositions();
}
function ChangePosition()
{
for(var i=0;i<cubeGameObjects.length;i++)
{
cubeGameObjects[i].transform.position;
}
slot.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
}
function AssignPositions()
{
for (var i = 0; i < cubesPosition.length; ++i)
cubeGameObjects[i].transform.position = cubesPosition[i];
}
function OnMouseUp() {
if(Vector3.Distance(transform.position,slot.position)==1)
{
xtemp = transform.position.x;
ytemp = transform.position.y;
transform.position.x=slot.position.x;
transform.position.y=slot.position.y;
slot.position.x = xtemp;
slot.position.y = ytemp;
}

Unity game engine having camera follow script transform change depending on car selected script?

OVERALL GOAL: Have the camera change target to the selected car
I'm new to the unity game engine and got a bit of a problem.
So, I have a successful car selector which changes between cars and starts the match with that car. Everything there works. The only issue is that my "CarCameraScript" has a transform variable which is always 1 of the 3 cars. I want it to change dependant on the selected car.
Here is the look at the code of the CarCameraScript
#pragma strict
var car : Transform;
var distance: float = 6.4;
var height: float = 1.4;
var rotationDamping : float = 3.0;
var heightDamping: float = 2.0;
var zoomRatio : float = 0.5;
var DefaultFOV : float = 60;
private var rotationVector : Vector3;
function Start () {
}
function LateUpdate () {
var wantedAngel = rotationVector.y;
var wantedHeight = car.position.y + height;
var myAngel = transform.eulerAngles.y;
var myHeight = transform.position.y;
myAngel = Mathf.LerpAngle(myAngel,wantedAngel,rotationDamping*Time.deltaTime);
myHeight = Mathf.Lerp(myHeight,wantedHeight,heightDamping*Time.deltaTime);
var currentRotation = Quaternion.Euler(0,myAngel,0);
transform.position = car.position;
transform.position -= currentRotation*Vector3.forward*distance;
transform.position.y = myHeight;
transform.LookAt(car);
}
function FixedUpdate () {
var localVilocity = car.InverseTransformDirection(car.rigidbody.velocity);
if (localVilocity.z<-0.5) {
rotationVector.y = car.eulerAngles.y + 180;
} else {
rotationVector.y = car.eulerAngles.y;
}
var acc = car.rigidbody.velocity.magnitude;
camera.fieldOfView = DefaultFOV + acc*zoomRatio;
}
This is what it looks like on the side panel.
http://i.stack.imgur.com/lYJP7.jpg
The area that says none (transform) is the place that should be variable dependant on the currently selected car.
Now, Here is my other script being the CharacterSelectScript
#pragma strict
//this is the currently selected Player. Also the one that will be saved to PlayerPrefs
var selectedPlayer : int = 0;
function Update()
{
if (Input.GetMouseButtonUp (0)) {
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit, 100))
{
// The pink text is where you would put the name of the object you want to click on (has attached collider).
if(hit.collider.name == "Player1")
SelectedCharacter1(); //Sends this click down to a function called "SelectedCharacter1(). Which is where all of our stuff happens.
if(hit.collider.name == "Player2")
SelectedCharacter2();
if(hit.collider.name == "Player3")
SelectedCharacter3();
}
else
{
return;
}
}
}
function SelectedCharacter1() {
Debug.Log ("Character 1 SELECTED"); //Print out in the Unity console which character was selected.
selectedPlayer = 1;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
function SelectedCharacter2() {
Debug.Log ("Character 2 SELECTED");
selectedPlayer = 2;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
function SelectedCharacter3() {
Debug.Log ("Character 3 SELECTED");
selectedPlayer = 3;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
How would I get it so that the SelectedPlayer changes the transform in the first script?
Any ideas?
I also have the prefab script which probably isnt important.
Also, should I join both scripts into one?
OVERALL GOAL: Have the camera change target to the selected car

Easeljs: Displayobject ontick event not work in for loop

i'm a newbie and i'm terrible at english but hopefully you can understand my problem
i create a simple space shooting game with easeljs, when i tried to create multiple bullets and assign an onTick handle to each one, i relize just one bullet fire out. Here is the code:
//handle fire(shooting)
if(fire && cd === 0){
for(var i=0; i<5; i++){
//codartjs.Bullet is a class extend createjs.Bitmap
var b = new codartjs.Bullet(bullet_img);
b.x = 200;
b.y = 200;
stage.addChild(b);
b.onTick = function(){
//this event handler work for only first instance
b.y -= 10;
};
}
cd = 100;
setTimeout(function(){
cd = 0;
},100);
}
What you can also try is having a central ticker and loop through each bullet element and update its position that way. Here is quick demo that will illustrate my point.
<script>
var canvas, stage;
var bullets;
var speed;
function init() {
stage = new createjs.Stage("test");
bullets = [];
var bg = new createjs.Shape();
bg.graphics.beginFill("#FFFFFF").drawRect(0, 0, stage.canvas.width, stage.canvas.height).endFill();
bg.cache(0, 0, stage.canvas.width, stage.canvas.height);
speed = 15;
stage.onClick = handleClick;
stage.mouseEnabled = true;
stage.enableMouseOver(10);
createjs.Ticker.setFPS(24);
stage.addChild(bg);
createjs.Ticker.addListener(window);
}
function getSprite() {
var s = new createjs.Shape();
s.graphics.beginFill("#000000").drawCircle(0, 0, 10).endFill();
return s;
}
function tick() {
for(var i=0;i<bullets.length;i++) {
var s = bullets[i];
s.x += speed;
}
stage.update();
}
function handleClick(event) {
var s = getSprite();
s.x = event.stageX;
s.y = event.stageY;
bullets.push(s);
stage.addChild(s);
}
</script>
Hope this helps.