f111fei / react-native-unity-view

Show an unity view in react native
MIT License
402 stars 102 forks source link

1.33 Android and iOS runtime issue: UnityModule is undefined #117

Open lmalave opened 5 years ago

lmalave commented 5 years ago

I am trying to follow the react-native-unity-demo example to integrate the UnityView component into my own app.

I import the module just like in the example:

import UnityView, { MessageHandler, UnityModule } from 'react-native-unity-view'; Whenever I try to execute a function on UnityModule (for example UnityModule.resume()), however, I get an error that UnityModule is undefined.

By outputting console.logs I've determined that UnityView and MessageHandler are defined, but UnityModule is not.

Has anyone else seen this issue? I am trying to integrate the latest version 1.3.3.

I should also not that the react-native-unity-demo is running fine for me. It's only when I integrate into my own app that I have this problem.

lmalave commented 5 years ago

Update: I built apps for both iOS and Android and in both cases I get the same issue of UnityModule undefined.

ziyoshams commented 5 years ago

Just get the ref from UnityView and it has the same methods as UnityModule.

alisherakb commented 5 years ago

Just get the ref from UnityView and it has the same methods as UnityModule.

Stuck on the same problem. Can you please check what might be wrong? Thank in advance!

react-native-unity-view: 1.3.3 Unity 2018.2.17


import { Text, View } from 'react-native';
import UnityView, { UnityModule } from 'react-native-unity-view';
import { TouchableOpacity } from 'react-native-gesture-handler';

export default class sad extends Component {
  togglePicker() {
    if (this.unity) {
      UnityModule.postMessage(
        'TogglePicker',
        `${colorId}`
      );
    }
  }
  render() {
    return (
      <SafeAreaView
        forceInset={{ top: 'always', bottom: 'always' }}
        style={styles.container}
      >
        <UnityView
          ref={ref => (this.unity = ref)}
          onMessage={this.onMessage.bind(this)}
        />
        <TouchableOpacity onPress={this.togglePicker()} />
      </SafeAreaView>
    );
  }
}```
lmalave commented 5 years ago

@ziyoshams I tried that before, but the problem is that if you look at the source code, the UnityView methods are just calling UnityModule: https://github.com/f111fei/react-native-unity-view/blob/master/src/UnityView.tsx

So since UnityModule is undefined, I am stuck at the same error.

ziyoshams commented 5 years ago

Just for reference, this is how I do it: I have a redux action to post to Unity because I send different messages from variety places in the app:

export const postToUnity = message => (dispatch, getState) => {
  const { unityView } = getState().ARReducer;
  if (!unityView) return;
  unityView.postMessageToUnityManager(message); <-- THIS IS THE GUY
};

And this action is dispatched from some other action like so:

export const someOtherAction = () => (dispatch, getState) => {
    {...}
    dispatch(postToUnity(JSON.stringify({ type: 'SOME_MESSAGE_TYPE', payload })));
};

In postToUnity action I get the ref that I called unityView to send the message. But I set that ref from the component:

class SomeComponent extends React.Component {

  // Messages that come from Unity
  onUnityMessage = event => {
    // event is stringified JSON.
    // contains Type of Action and Payload

    const action = JSON.parse(event);
    this.props.handleUnityActions(action); <-- Just a switch statement
  };

  render() {
     return (
       <View style={styles.container}>
          <UnityView
              ref={ref => this.props.setUnityView(ref)}
              style={StyleSheet.absoluteFill}
              onMessage={this.onUnityMessage}
          />
       </View>
     );
   }
  // this.props.setUnityView stores the ref in my redux store (ARReducer)
}

And on the Unity side we parse the strings and act accordingly by the type of the message. The whole thing works.

lmalave commented 5 years ago

@ziyoshams Thanks again for your help!

Which version of react-native-unity-module are you using? I am using 1.3.3 and when I look at the definition in UnityView for postMessageToUnityManager it's this:

/**
 * [Deprecated] Use `UnityModule.postMessageToUnityManager` instead.
 */
public postMessageToUnityManager(message: string | UnityViewMessage) {
    UnityModule.postMessageToUnityManager(message);
};

So it's just a wrapper around UnityModule. In my case UnityModule is undefined, so I get an error.

lmalave commented 5 years ago

Update: I tried with version "^1.3.0", since that's what's used the react-native-unity-demo project, but I have the same result.

One thing about my project, though, is that when I tried to build originally, I got that the Unity classes were missing, so by reading other issues in this repo I found the suggestion too add the following to the build.gradle of the node_module for react-native-unity-view:

implementation files('../../../android/UnityExport/libs/unity-classes.jar')

This fixed the build error, but maybe it's related to the runtime error I am seeing? Maybe UnityModule can't load because it can't find the Unity classes at runtime?

lmalave commented 5 years ago

Ok, I was able to resolve the issue at least for Android. I just had to make sure that this line of code was included in the Build.js file:

    build_text = build_text.Replace("implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])", "api fileTree(include: ['*.jar'], dir: 'libs')");

I was also getting the issue in iOS, though, so I will have to verify that is working and then I will close.

ziyoshams commented 5 years ago

@lmalave I am using 1.3.3. But my set up is from 1.1.3. I could not get it working with UnityModule. Thats why I suggested to use ref.