Closed FlorianLance closed 1 year ago
You are doing a mix between C# function and C# script components. C# function is mostly for creating small utility function for doing the glue between nodes and others scripts. C# script have may more functionalities:
For using them you have to click on the "Display resources manager" button or from the menu ("Resources/Display resources manager")
Click on the C# script panel, and from this place you can either add a previously created C# script or to create a new one using the "Generate script" button.
By doing the later, it open a popup window: You have to choose the component name (you will have to refer by this name from the C# script component later)
Once the destination validated, you can open it by clicking on "Open file", (it will use the default editor for .cs files, so if you have installed Visual studio it will be opened with it)
Once open you will be able to seen a bunch of functions you can comment or uncomment, every component in ExVR is using theses functions:
Below you can see the documentation of the main classes inherited by the script.
You now have to reference your script component by setting its name:
So if you use the code you wrote inside the initialize or the start_routine functions for example and if you have a Cube component in your scene named "cube_component_name", it will now work.
public override bool initialize() {
var modelComponent = (CubeComponent)get("cube_component_name");
log_message(modelComponent.name);
return true;
}
It's because the TemplateComponent we just created is inheriting from BaseCompiledCSharpComponent and contains a lot of quality of life functionnalites.
One important thing regarding transforms with model components:
From the initialization config panel, the transform will be only applied once (except if you check Do not apply) when you load the experiment by clicking on one of theses buttons:
But from the Conditions configs panel:
Each time you start a routine with a condition referencing this component config, it will apply the Config transform, except if you check Do not apply
.
So if you wish to control the transform of this component only from scripting or visual scripting, I encourage you to check the Do not apply button at least for the Conditions config panel.
After from you script you can use either of theses methods to update the component position:
// you can move/resize the model with:
// # a list of 3 Vector3 (postion,rotation,scale)
List<Vector3> listV = new List<Vector3>();
listV.Add(new Vector3(0,2f,0)); // position
listV.Add(new Vector3(30f,0,0)); // rotation
listV.Add(Vector3.one); // scale
modelConfig.set_transform("transform", listV);
// # a TransformValue
TransformValue trV = new TransformValue();
trV.position = new Vector3(0,2f,0);
trV.rotation = Quaternion.Euler(new Vector3(30f,0,0));
trV.scale = Vector3.one;
modelConfig.set_transform("transform", trV);
// # a Transform
Transform tr = someGameObject.transform;
modelConfig.set_transform("transform", tr);
// apply changes
modelComponent.update_from_current_config();`
So your final script may be like this:
// system
using System;
using System.Reflection;
using System.Collections.Generic;
// unity
using UnityEngine;
namespace Ex{
public class TemplateComponent : BaseCompiledCSharpComponent{
CubeComponent cube = null;
// Ex component flow functions, uncomment to use
// # once per loading
public override bool initialize() {
cube = (CubeComponent)get("cube_component_name");
return true;
}
public override void update() {
// # a TransformValue
TransformValue trV = new TransformValue();
trV.position = new Vector3(..., ..., ...);
trV.rotation = Quaternion.Euler(new Vector3(..., ..., ...));
trV.scale = Vector3.one;
cube.current_config().set_transform("transform", trV);
}
}
}
The template file generated by the component is a bit out of date, I'll update it.
Thank you for the amazing support.
Below is my attempt to read the keyboard input from slot 5:
#################### // system using System; using System.Reflection; using System.Collections.Generic;
// unity using UnityEngine;
namespace Ex{
public class CS_move_cube : BaseCompiledCSharpComponent{
CubeComponent Cube = null;
// Ex component flow functions, uncomment to use
// # once per loading
public override bool initialize() {
Cube = (CubeComponent)get("Cube");
return true;
}
public override void update() {
var CubeConfig = Cube.current_config();
Vector3 CubePos = CubeConfig.get<Vector3>("position");
float CubeHeight = CubePos.y;
var idV = (IdAny)slot5;
if(idV.id == 0){
CubeHeight += 0.1f;
}else if(idV.id == 1){
CubeHeight -= 0.1f;
}
// # a TransformValue
TransformValue trV = new TransformValue();
trV.position = new Vector3(CubePos.x, CubeHeight, CubePos.z);
trV.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
trV.scale = Vector3.one;
Cube.current_config().set_transform("transform", trV);
}
}
}
################
I get the following error:
[COMPILER] Compilation error CS0428 : "Cannot convert method group slot5' to non-delegate type
Ex.IdAny'. Consider using parentheses to invoke the method" from file D:/Michel/ExVR/PPS_reaching/assets/CS_move_cube.cs at line 27 and column 25
################ The connections:
###############
An alternative would be the read directly the keyboard within the script. If this would be the preferred way, what is the correct way to "catch" the latest pressed key ? last_event() or send_infos_and_signals()
I would like to modify the CS function that moves a VR object to directly modify the config so that the changes remains in next routines. I saw this documentation for the cube component:
Content:
How to us this syntax inside the CS function ?
If I just use:
var modelComponent = (CubeComponent)get("cube_component_name");
'get' is not recognized
if I add something like this in the extra section
'using' is not recognized
I also tried the CS script component, but I don't understand how it works (adding elements, no scripting at all ?)
Thanks in advance.
Originally posted by @makselro in https://github.com/BlankeLab/ExVR/issues/3#issuecomment-1742783134