How do i use an arduino controller and a keyboard at the same time? - unity3d

How do I use a controller and keyboard at the same time?
So I use an Arduino as my controller using ReadByte() as my input
Here is my script for my player
void Start()
{
controller = GetComponent<Controller2D>(); // Je krijgt toegang tot de script Controller2D
sp.DtrEnable = true;
sp.ReadTimeout = 100;
sp.Open(); // Uw serialpoort openen
}
void Update()
{
if (sp.IsOpen) // Als uw serialpoort open is
{
try
{
print(sp.ReadByte()); // Ga je de inkomende waarde lezen
}
catch (System.Exception) { }
}
if (controller.collisions.above || controller.collisions.below) // Als je een botsing hebt van boven of beneden dan ga je stoppen met springen
{
moveDistance.y = 0;
}
if (Input.GetKeyDown(KeyCode.Space) || sp.ReadByte() == 1 && controller.collisions.below) // Als je op spatie drukt en als je op een platform staat dan ga je boven springen
{
moveDistance.y = jumpDistance; // Je gaat springen langs de y-as
//moveDistance.x = 0; // Als je alleen springt dan ga je loodrecht boven en niet schuin
}
Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")); // Je neemt de Horizontal en vertical inputs van de unity zelf
if (sp.ReadByte() == 2) // Als je de 2de drukknop indrukt
{
moveDistance.x = -moveSpeed ; // Ga je links bewegen
}
if (sp.ReadByte() == 3) // Als je de 3de druknop indrukt
{
moveDistance.x = moveSpeed; // Ga je rechts bewegen
}
moveDistance.x = input.x * moveSpeed; // Door input kan je nu links of rechts bewegen met de pijlen
moveDistance.y += gravity * Time.deltaTime; // Je valt met een zwaartekracht dus je gaat sneller en sneller vallen.
controller.Move(moveDistance * Time.deltaTime); // Leest de input
}
Normally I would want to have both controller and keyboard as my inputs but after I run this game I immediatly get a
TimeoutException: the operation has timed out
error but I can use the Arduino as inputs but it's just the keyboard that gets disabled for some reason

Might be the cause of the error not sure but in general I would not use sp.ReadByte() repeatedly but only once, store the value and compare that:
void Update()
{
byte arduinoInput = 0;
if (sp.IsOpen) // Als uw serialpoort open is
{
try
{
arduinoInput = sp.ReadByte();
print(arduinoInput); // Ga je de inkomende waarde lezen
}
catch (System.Exception) { }
}
if (controller.collisions.above || controller.collisions.below) // Als je een botsing hebt van boven of beneden dan ga je stoppen met springen
{
moveDistance.y = 0;
}
if (Input.GetKeyDown(KeyCode.Space) || arduinoInput == 1 && controller.collisions.below) // Als je op spatie drukt en als je op een platform staat dan ga je boven springen
{
moveDistance.y = jumpDistance; // Je gaat springen langs de y-as
//moveDistance.x = 0; // Als je alleen springt dan ga je loodrecht boven en niet schuin
}
Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")); // Je neemt de Horizontal en vertical inputs van de unity zelf
if (arduinoInput == 2) // Als je de 2de drukknop indrukt
{
moveDistance.x = -moveSpeed ; // Ga je links bewegen
}
if (arduinoInput == 3) // Als je de 3de druknop indrukt
{
moveDistance.x = moveSpeed; // Ga je rechts bewegen
}
moveDistance.x = input.x * moveSpeed; // Door input kan je nu links of rechts bewegen met de pijlen
moveDistance.y += gravity * Time.deltaTime; // Je valt met een zwaartekracht dus je gaat sneller en sneller vallen.
controller.Move(moveDistance * Time.deltaTime); // Leest de input
}
The errors are probably thrown for frames when the port is not open yet bt you already tried to read or simply caused by the multiple access.

Related

NumberFormat - Currency

I have a problem with my code.
I send a number but the format does not working.
My code is the next.
class SetValueClass extends HelperClass {
SetValueClass() : super();
String transformValue({
required double number,
bool? pasa,
}) {
number = 27126677097.04;
SuffixOptions suffixOptions = getSuffixObject(number);
if (pasa != null && pasa) {
print(number);
print(suffixOptions.name);
print(suffixOptions.format);
print(suffixOptions.number);
print(suffixOptions.suffix);
}
final numberFormat = NumberFormat.currency(
locale: 'es_CO',
// customPattern: '',
symbol: suffixOptions.suffix,
);
numberFormat.maximumFractionDigits = suffixOptions.format['maximumFractionDigits']!;
numberFormat.minimumFractionDigits = suffixOptions.format['minimumFractionDigits']!;
return numberFormat.format(number);
}
}
The final result i want, is parse 27126677097.04 to 27,127 MM, but y received this...
27.126.677.097,04 MM
The symbol is working successfully, but, ¿how can i compact this number and return 27,127 MM?
Note: The locale es_CO is the code of Colombia.
Thanks!
After some research, I realized that the es_CO did not work the way I needed it to, so I decided to go with the following solution.
Create a function.
String _defineValue({required number}) {
/**
* Valor en el rango de cuatrillones.
* (C)
*/
if (number > 1e+24) {
return "${(number / 1e+24).toStringAsFixed(2)} C";
}
/**
* Valor en el rango de miles de trillones.
* (MT)
*/
if (number > 1e+21) {
return "${(number / 1e+21).toStringAsFixed(3)} MT";
}
/**
* Valor en el rango de trillones.
* (T)
*/
if (number > 1e+18) {
return "${(number / 1e+18).toStringAsFixed(2)} T";
}
/**
* Valor en el rango de miles de billones.
* (MB)
*/
if (number > 1e+15) {
return "${(number / 1e+15).toStringAsFixed(3)} MB";
}
/**
* Valor en el rango de billones.
* (MB)
*/
if (number > 1e+12) {
return "${(number / 1e+12).toStringAsFixed(2)} B";
}
/**
* Valor en el rango de miles de millones.
* (MM)
*/
if (number > 1e+9) {
return "${(number / 1e+9).toStringAsFixed(3)} MM";
}
/**
* Valor en el rango de millones.
* (M)
*/
if (number > 1e+6) {
return "${(number / 1e+6).toStringAsFixed(2)} M";
}
/**
* Valor en el rango de inferior
*/
return "${(number / 1).toStringAsFixed(0)}";
}
This function gets a number and return a String with the logic required in my case.

STM32 I2S with DMA playing slow

I want to implement a WAV/MP3 player(now let's just say WAV) with an STM32, it reads it from the SD with FATFS, then transfer it to the I2S buffer with DMA.
The problem is that when I plug my speakers, it plays the song at the correct pitch(tone) but very slowly, and it also does an strange repetitive tick, is like the buffer is filled slowly, or played slowly, but with the correct frequencies.
I use an STM32_F4VE(STM32F407VET6) with a PCM5102(only needs DATA, BCK at 32xfs for 16bits, and LRCK at fs)
Here I attach a few code parts:
main.c
if(res = f_mount(&SDFatFS, SDPath, 1) == FR_OK){ //If SD card is correctly mounted
HAL_UART_Transmit_IT(&huart1, "SD montada correctamente\n\r", strlen("SD montada correctamente\n\r"));
if(wavPlayer_fileSelect("test.wav") == 0){ //If the wav file wasn't correstly opened
HAL_UART_Transmit_IT(&huart1, "Error al abrir el WAV\n\r", strlen("Error al abrir el WAV\n\r"));
}
else
{
HAL_UART_Transmit_IT(&huart1, "WAV abierto\n\r", strlen("WAV abierto\n\r"));
wavPlayer_play();
HAL_UART_Transmit_IT(&huart1, "WAV PLAY\n\r", strlen("WAV PLAY\n\r"));
isPlaying = true;
}
}
else
{
HAL_UART_Transmit_IT(&huart1, "Error al montar la SD\n\r", strlen("Error al montar la SD\n\r"));
}
wavplayer.c
/**
* #brief Select WAV file to play
* #retval returns true when file is found in USB Drive
*/
bool wavPlayer_fileSelect(const char* filePath)
{
UINT readBytes = 0;
//Open WAV file
if(f_open(&wavFile, filePath, FA_READ) != FR_OK)
{
return false;
}
//Read WAV file Header
f_read(&wavFile, &wavHeader, sizeof(wavHeader), &readBytes);
sprintf(UART_buff, "Tamaño del archivo: %d\n\rFrecuencia de muestreo: %d\n\r", wavHeader.FileSize, wavHeader.SampleRate);
HAL_UART_Transmit_IT(&huart1, UART_buff, strlen(UART_buff));//TX Function
end_of_file_reached = false;
return true;
}
/**
* #brief WAV File Play
*/
void wavPlayer_play(void)
{
isFinished = false;
//Read Audio data from USB Disk
f_lseek(&wavFile, 0);
f_read (&wavFile, &audioBuffer[0], AUDIO_BUFFER_SIZE, &playerReadBytes);
audioRemainSize = wavHeader.FileSize - playerReadBytes;
//Start playing the WAV
HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t *)&audioBuffer[0], AUDIO_BUFFER_SIZE);
}
/**
* #brief Half/Full transfer Audio callback for buffer management
*/
void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
{
if(hi2s->Instance == SPI2)
{
if(end_of_file_reached){
return;
}
res = f_read (&wavFile, &audioBuffer[AUDIO_BUFFER_SIZE/2], AUDIO_BUFFER_SIZE/2, &playerReadBytes);
if(audioRemainSize > (AUDIO_BUFFER_SIZE / 2))
{
audioRemainSize -= playerReadBytes;
}
else
{
audioRemainSize = 0;
end_of_file_reached = true;
}
}
}
void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
if(hi2s->Instance == SPI2)
{
if(end_of_file_reached){
return;
}
res = f_read (&wavFile, &audioBuffer[0], AUDIO_BUFFER_SIZE/2, &playerReadBytes);
if(audioRemainSize > (AUDIO_BUFFER_SIZE / 2))
{
audioRemainSize -= playerReadBytes;
}
else
{
audioRemainSize = 0;
end_of_file_reached = true;
}
}
}

Unity 3D: How I can make a Player with a Character Controller can push another Player with Character Controller?

I'm new into unity and I'm following tutorials. I'm making a script that moves a 3D player with a CharacterController and I attached another script that adds the ability to push RigidBodys, but how I can make the Player push another Player? It just collides but nothing happens and I don't want to make it a rigidbody.
//Script that i use as PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float horizontalMove;
public float verticalMove;
private Vector3 playerInput;
public CharacterController player;
public float playerSpeed;
public Vector3 movePlayer;
public float gravity = 9.8f;
public float fallVelocity;
public float jumpForce;
public Camera mainCamera;
private Vector3 camForward;
private Vector3 camRight;
public bool isOnSlope = false;
private Vector3 hitNormal;
public float slideVelocity;
public float slopeForceDown;
private PushRigidBody pushRigid;
public float pushPlus;
// Start is called before the first frame update
void Start()
{
player = GetComponent<CharacterController>();
//Obtengo el componente Script "PushRigidBody" para poder usar sus metodos y cambiar variables con sus mutadores
pushRigid = GetComponent<PushRigidBody>();
}
// Update is called once per frame
void Update()
{
horizontalMove = Input.GetAxis("Horizontal");
verticalMove = Input.GetAxis("Vertical");
playerInput = new Vector3(horizontalMove, 0, verticalMove);
playerInput = Vector3.ClampMagnitude(playerInput, 1);
camDirection();
movePlayer = playerInput.x * camRight + playerInput.z * camForward;
movePlayer = movePlayer * playerSpeed;
player.transform.LookAt(player.transform.position + movePlayer);
SetGravity();
PlayerSkills();
player.Move(movePlayer * playerSpeed * Time.deltaTime);
}
private void FixedUpdate()
{
}
void camDirection()
{
camForward = mainCamera.transform.forward;
camRight = mainCamera.transform.right;
camForward.y = 0;
camRight.y = 0;
camForward = camForward.normalized;
camRight = camRight.normalized;
}
//Funcion para habilidades de jugador
public void PlayerSkills()
{
if (player.isGrounded && Input.GetButtonDown("Jump"))
{
fallVelocity = jumpForce;
movePlayer.y = fallVelocity;
}
//Detecta si presiono la tecla para golpear objeto y aventarlo, si la aprieta aumenta la fuerza con la que golpea, si no, la vuelve a dejar como estaba
if (Input.GetButton("Fire1"))
{
pushRigid.SetPushPower(pushPlus);
}
else
{
pushRigid.SetPushPower( 0f );
}
}
void SetMov(Vector3 vector)
{
movePlayer = movePlayer - vector;
}
void SetGravity()
{
if (player.isGrounded)
{
fallVelocity = -gravity * Time.deltaTime;
movePlayer.y = fallVelocity;
}
else
{
fallVelocity -= gravity * Time.deltaTime;
movePlayer.y = fallVelocity;
}
SlideDown();
}
//Compara si esta o no en una rampa y aplica fuerzas para deslizar
public void SlideDown()
{
//isOnSlope = angulo >= angulo maximo del charcontroller
isOnSlope = Vector3.Angle(Vector3.up, hitNormal) >= player.slopeLimit;
if (isOnSlope)
{
movePlayer.x += ((1f - hitNormal.y) * hitNormal.x) * slideVelocity;
movePlayer.z += ((1f - hitNormal.y) * hitNormal.z) * slideVelocity;
movePlayer.y += slopeForceDown;
}
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
hitNormal = hit.normal;
}
}
----------
///Script that i use for push rigidbodys
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PushRigidBody : MonoBehaviour
{
public float pushPower = 2.0f;
private float pushPowerPlus = 0f;
private void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
if (body == null || body.isKinematic)
{
return;
}
//Si caemos encima de un objeto no queremos empujarlo, se pone encima de el
if (hit.moveDirection.y < -0.8)
{
return;
}
Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
;
body.velocity = pushDir * (pushPower + pushPowerPlus);
}
public void SetPushPower(float pushPowerVar)
{
pushPowerPlus = pushPowerVar;
}
}
If you don't want to use a RigidBody to move the character, it is easier if you also don't use a RigidBody for pushing, and implement it as you did using the body.move on the update (which forces the body to move every game tick)
So you could add a new Vector to the players, the push force, and when you collide you set the push force vector of the other player you collided with.
Then on the update, you add the push vector to the movement when calling move and make it lower until it reaches 0 to create the feel of deaceleration.
You can use the built in linear interpolation in Unity (Lerp) to make this "vector smoothly go down to zero".
Two ways to do this
1. Add Collider and rigidBody (both required) to object to be pushed and object that'll push and use RigidBody's MovePosition RigidBody.MovePosition functionality for moving object that'll push then it'll push other rigid bodies unity's physics engine when it moves toward them.
2. If you want to push objects on a certain event happening you can do all the above but on the event happening you can use Rigidbody's AddForce RigidBody.AddForce functionality.
Good Luck!
Edit: I believe CharachterController acts as a collider in GameObjects so you may not need to add colliders.

How to re-launch the scan in LEX

I am trying to do a conversor from markdown syntax to Latex and vice versa. But I am facing a problem I can not solve so far. Lets say, we have the following text:
* item
* item
* _Italic_ item
* Item with __nested _italic_ text__
Right now, my lex program would do this to the text:
\begin{itemize}
\item{item}
\item{item}
\item{_Italic_ item}
\item{Item with __nested _italic_ text__}
\end{itemize}
And, if I run the program again on that output, I get:
\begin{itemize}
\item{item}
\item{item}
\item{\textit{Italic} item}
\item{Item with nested \textit{italic} text}}
\end{itemize}
Which is the expected result, But it is supposed to do it in one run.
I want to know if it is possible to indicate Flex to run yylex() again on the output. Reading the documentation I've found something about Reentrant C Scanners and Multiple Input Buffers, but I do not know if that would solve my problem.
What is the best solution? Reentrant scanners, multiple Input buffers, or something more simpler?
I also thought on implementing the function yywrap to tell lex launch the scanner again, but with no luck:
int yywrap(){
if (first_run == 1){
first_run++;
yyin = fopen ("/tmp/out1", "rt");
yyout = fopen("salida", "wt");
if (yyin == NULL) {
printf ("El fichero no se puede abrir\n");
exit (-1);
}
if (yyout == NULL) {
printf ("El fichero no se puede abrir\n");
exit (-1);
}
yyrestart(yyin);
return 0;
} else {
return 1;
}
}
Here is my code:
/*----- Sección de Declaraciones --------------*/
%option case-insensitive
%option debug
%option verbose
%{
#include<stdio.h>
#include<string.h>
int from_italic_text = 0; /* Para saber si venimos de una italic anidada en la bold*/
int from_bold_text = 0;
%}
/* Primitives */
word .+
scstrong "__"|"**"
scem "_"|"*"
list ^"* "|"- "
%x IN_MARKDOWN_LIST
%x BOLD_TEXT_NESTED_ITALIC ITALIC_TEXT
%x BOLD_TEXT ITALIC_TEXT_NESTED_BOLD
%%
/*----- Sección de Reglas ----------------*/
{list} {BEGIN(IN_MARKDOWN_LIST);fprintf(yyout, "\\begin{itemize}\n");}
<IN_MARKDOWN_LIST>{
^\n fprintf(yyout, "\\end{itemize}\n\n");BEGIN(INITIAL); /* si volvemos a detectar línea vacia, hemos acabado el itemize, o no era nada y salimos */
^"* "|"- " /* Eliminar la sintáxis de itemize en markdown */
[^"*"\-\n]+ fprintf(yyout, "\t\\item{%s}\n", yytext); /* Éste es el texto que compone cada línea del itemize */
\n yylineno++;BEGIN(IN_MARKDOWN_LIST); /* Si detectamos salto de línea, aumentar el número de línea, y seguimos comprobando dentro de IN_MARKDOWN_LIST buscando más items*/
}
{scstrong} { BEGIN(BOLD_TEXT_NESTED_ITALIC); /* Comienzo de un strong __....*/}
<BOLD_TEXT_NESTED_ITALIC>{
"__" fprintf(yyout, "}");BEGIN(INITIAL); // Eat the end and exit
"_" BEGIN(ITALIC_TEXT); // Hay otro elemento anidado, un italic, pasamos a procesarlo
[^_\n]* {
if (from_italic_text)
fprintf(yyout, "%s", yytext); // Texto a continuación del italic
else
fprintf(yyout, "\\textbf{%s", yytext);
}
\n BEGIN(INITIAL);
}
<ITALIC_TEXT>{
[^_\n]* fprintf(yyout, "\\textit{%s", yytext);
"_" fprintf(yyout, "}"); BEGIN(BOLD_TEXT_NESTED_ITALIC); from_italic_text = 1; /* Llegado al último _, cerramos }, volvemos al stado BOLD_TEXT y ponemos from_italic_text a 1 para saber que estuvimos aquí, y no cerra antes de tiempo el \textbf*/
}
{scem} { BEGIN(ITALIC_TEXT_NESTED_BOLD); /* Comienzo de un strong __....*/}
<ITALIC_TEXT_NESTED_BOLD>{
"_" fprintf(yyout, "}"); BEGIN(INITIAL); // Eat the end and exit
"__" BEGIN(BOLD_TEXT); // Hay otro elemento anidado, un italic, pasamos a procesarlo
[^_\n]* {
if (from_bold_text)
fprintf(yyout, "%s", yytext); // Texto a continuación del italic
else
fprintf(yyout, "\\textit{%s", yytext);
}
\n BEGIN(INITIAL);
}
<BOLD_TEXT>{
[^_\n]* fprintf(yyout, "\\textbf{%s", yytext);
"__" fprintf(yyout, "}"); BEGIN(ITALIC_TEXT_NESTED_BOLD); from_bold_text = 1; /* Llegado al último _, cerramos }, volvemos al stado BOLD_TEXT y ponemos from_italic_text a 1 para saber que estuvimos aquí, y no cerra antes de tiempo el \textbf*/
}
.|\n {ECHO;}
%%
/*----- Sección de Procedimientos --------*/
int main (int argc, char *argv[]) {
if (argc == 2) {
yyin = fopen (argv[1], "rt");
if (yyin == NULL) {
printf ("El fichero %s no se puede abrir\n", argv[1]);
exit (-1);
}
} else
yyin = stdin;
yyout = fopen("/tmp/out1", "wt");
if (yyout == NULL) {
printf ("El fichero %s no se puede abrir\n", argv[1]);
exit (-1);
}
yylex ();
return 0;
}
Instead of doing multiple traversals you do it with a single traversal and stacks:
%option stack
and change BEGIN state with
yy_push_state(STATE) // ... push current-state; BEGIN STATE
yy_pop_state // instead of BEGIN INITIAL we "return" to prev. state
This way easily have nested commands
{list} { yy_push_state(IN_MARKDOWN_LIST);fprintf(yyout, "\\begin{itemize}\n");}
<IN_MARKDOWN_LIST>{
^\n { yy_pop_state(); fprintf(yyout, "\\end{itemize}\n\n");
"__" { yy_push_state(BOLD); fprintf(yyout, "\\textbf{");
"_" { yy_push_state(ITALIC); fprintf(yyout, "\\textit{");
...
}
<ITALIC>{
"_" { yy_pop_state(); fprintf(yyout, "}"); }
....
. { fprintf(yyout, "%s",yytext);}
}
I finally came out with a solution. I do not know if it is the best, but it worked. I implemented yywrap like this:
int yywrap(){
if (first_run == 1){
first_run++;
fclose(yyout);
fclose(yyin);
yyin = fopen ("/tmp/out", "rt");
yyout = fopen("salida", "wt");
if (yyin == NULL) {
printf ("El fichero no se puede abrir\n");
exit (-1);
}
if (yyout == NULL) {
printf ("El fichero no se puede abrir\n");
exit (-1);
}
return 0;
} else {
return 1;
}
}
int main (int argc, char *argv[]) {
yyin = fopen (argv[1], "rt");
// ...
yyout = fopen("/tmp/out", "wt");
// .....
yylex();
}

Invoke not working Unity

Can you tell me what's wrong in this piece of code? It does not call the Invoke function
public class ReazioneBonus : MonoBehaviour {
void OnTriggerEnter(Collider collider){
string nomeBonus;
if(collider.gameObject.name.Contains("Pallina")){
nomeBonus = gameObject.name;
Debug.Log("bonus colpito");
Debug.Log("il nome del bonus è " + nomeBonus);
if(nomeBonus == "PaddleLungo(Clone)"){ //Allunga il paddle per 5 secondi
Debug.Log("attivazione Paddle Lungo");
Destroy(gameObject);
Debug.Log("bonus colpito da " + Pallina.ultimoGiocatoreToccato);
if(Pallina.ultimoGiocatoreToccato.name == "AvversarioRosso" || Pallina.ultimoGiocatoreToccato.name == "AvversarioVerde"){
Debug.Log("giocatore riconosciuto");
AllungaPaddleVerticale();
Invoke ("RipristinaPadVerticale", 5f); //non chiama la funzione
}else if(Pallina.ultimoGiocatoreToccato.name == "AvversarioBlu" || Pallina.ultimoGiocatoreToccato.name == "AvversarioGiallo"){
Debug.Log("giocatore riconosciuto");
AllungaPaddleOrizzontale();
Invoke ("RipristinaPadOrizzontale", 5f); //non chiama la funzione
}
}
}
}
void AllungaPaddleVerticale(){
Pallina.ultimoGiocatoreToccato.transform.localScale += new Vector3(3F, 0, 0);
}
void AllungaPaddleOrizzontale(){
Pallina.ultimoGiocatoreToccato.transform.localScale += new Vector3(0, 0, 3F);
}
void RipristinaPadVerticale(){
Debug.Log("ripristino il paddle");
Pallina.ultimoGiocatoreToccato.transform.localScale += new Vector3(-3F, 0, 0);
}
void RipristinaPadOrizzontale(){
Debug.Log("ripristino il paddle");
Pallina.ultimoGiocatoreToccato.transform.localScale += new Vector3(0, 0, -3F);
}
}
You destroy the gameObject of that monobehavior:
Destroy(gameObject);
How would these methods be invoked if the monobehavior itself is already destroyed?
When you destroy a GameObject all attached MonoBehaviours' active invokes are cancelled. This to prevent bad references.
Simply destroy the GameObject after your invokes are complete:
public class ReazioneBonus : MonoBehaviour {
void OnTriggerEnter(Collider collider){
string nomeBonus;
if(collider.gameObject.name.Contains("Pallina")){
nomeBonus = gameObject.name;
Debug.Log("bonus colpito");
Debug.Log("il nome del bonus è " + nomeBonus);
if(nomeBonus == "PaddleLungo(Clone)"){ //Allunga il paddle per 5 secondi
Debug.Log("attivazione Paddle Lungo");
Debug.Log("bonus colpito da " + Pallina.ultimoGiocatoreToccato);
if(Pallina.ultimoGiocatoreToccato.name == "AvversarioRosso" || Pallina.ultimoGiocatoreToccato.name == "AvversarioVerde"){
Debug.Log("giocatore riconosciuto");
AllungaPaddleVerticale();
Invoke ("RipristinaPadVerticale", 5f); //non chiama la funzione
}else if(Pallina.ultimoGiocatoreToccato.name == "AvversarioBlu" || Pallina.ultimoGiocatoreToccato.name == "AvversarioGiallo"){
Debug.Log("giocatore riconosciuto");
AllungaPaddleOrizzontale();
Invoke ("RipristinaPadOrizzontale", 5f); //non chiama la funzione
}
}
}
}
void AllungaPaddleVerticale(){
Pallina.ultimoGiocatoreToccato.transform.localScale += new Vector3(3F, 0, 0);
}
void AllungaPaddleOrizzontale(){
Pallina.ultimoGiocatoreToccato.transform.localScale += new Vector3(0, 0, 3F);
}
void RipristinaPadVerticale(){
Debug.Log("ripristino il paddle");
Pallina.ultimoGiocatoreToccato.transform.localScale += new Vector3(-3F, 0, 0);
Destroy(gameObject);
}
void RipristinaPadOrizzontale(){
Debug.Log("ripristino il paddle");
Pallina.ultimoGiocatoreToccato.transform.localScale += new Vector3(0, 0, -3F);
Destroy(gameObject);
}
}