React-Native接入Unity导出项目,展示3D模型

本文介绍如何将Unity3D项目嵌入React Native应用中,实现3D模型的展示。通过具体步骤指导如何配置Xcode、Unity3D导出设置及React Native组件开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:http://blog.youkuaiyun.com/pz789as/article/details/52604075


今天突然想到在RN里面展示一些3D模型,这样可以增加软件的表现力。

我首先想到的是Unity3D,因为以前做过Unity3D的项目,它使用简单,最主要是用C#语言,对于我这个以前用C/C++的人来,是一个很不错的开发工具。

使用的版本:Xcode:7.3.1 Unity3D:5.3.5f1  RN:React:15.3.2,React-Native:0.33.0

那么开始记录我的做法:

首先,分别创建RN项目(Jicheng5)和Unity3D项目(RunInRN),我这里Unity3D项目没做什么特别的,只在场景里面放了一个Cube,然后加了一个脚本,让它自动旋转。



第二步,导出Unity项目,当然我们要选择导出ios才可以,打开file -》build settings 选中iOS,然后可以设置,其他设置不多说了,可以在网上看教程,我都是默认设置。需要注意5点:

1.Auto Graphic API: 去掉钩,然后选择OpenGLES2

2.Scripting Backend:选择IL2CPP

3.Target Device: 根据需要选择,我这里是默认的iPhone+iPad

4.Target SDK:一般默认是Device SDK,如果是这个,那么导出之后只能在真机上看效果,我现在是这个,如果你希望能在模拟器上看效果,可以选择Simulator SDK,不过这样你就不能发布了。

5.Target minimum iOS Version:选择8.0或以上。

以上这些设置之后,就可以点build按钮,选择路径到我们RN的根目录下面去,然后导出(unityVIew)

                 


第三步,看到上面导出的目录结构没,现在我们把unityView里面的Classes、Data、Libraries、MapFileParser、MapFileParser.sh拷贝到ios目录下面去

                      


打开ios里面的xcode工程,导入Classes和Libraries,导入时选择Create groups



而导入Data时,需要选择Create folder reference:



第四步:设置Xcode的参数:

1,选中Jicheng5 -》 build Phases,左上有个“+”号,点击添加run script,shell下面添加 "$PROJECT_DIR/MapFileParser.sh"

2,选择Link Binary With Libraries,将截图里面缺少的framework都加上:

      

3,选择Build Settings,搜索到Search Paths,在Header Search Paths中添加:注意引号

"$(SRCROOT)"

"$(SRCROOT)/Classes"

$(SRCROOT)/Classes/Native

$(SRCROOT)/Libraries/bdwgc/include

$(SRCROOT)/Libraries/libil2cpp/include

在Library Search Paths中添加:

"$(SRCROOT)"

"$(SRCROOT)/Libraries"

4,修改main.m,将Classes里面的main.mm中的所有内容拷贝至自己项目的main.m中,可以先将main.m里面的注释掉,然后粘贴拷贝的内容,把自己项目下的main.m重命名为main.mm,最后把Classes里面的main.mm删除。选择remove reference即可。

把mian.mm里面的修改一下:

void UnityInitTrampoline();

// WARNING: this MUST be c decl (NSString ctor will be called after +load, so we cant really change its value)
const char* AppControllerClassName = "AppDelegate";//将原来的UnityAppController改为AppDelegate

#import <UIKit/UIKit.h>//额外添加的
#import "AppDelegate.h"//<span style="font-family: Arial, Helvetica, sans-serif;">额外添加的</span>


int main(int argc, char* argv[])
{
  @autoreleasepool


5,选择Jicheng5Targets =》 Build Settings 搜索Prefix Header,添加Prefix Header内容: Classes/Prefix.pch

6,还是Build Settings中搜索Other C Flags,修改值为-DINIT_SCRIPTING_BACKEND=1

7,搜索Bitcode,将值设置为NO。

8,修改Classes中的UnityAppController.h中的内容:

inline UnityAppController*	GetAppController()
{
//	return (UnityAppController*)[UIApplication sharedApplication].delegate;
  return (UnityAppController*)[[UIApplication sharedApplication] valueForKeyPath:@"delegate.unityAppController"];
}
这里是把UnityAppController保存在AppDelegate中了,所以只要从delegate中获取就可以了。

9,在AppDelegate.h文件中添加UnityAppController

#import <UIKit/UIKit.h>
#import "UnityAppController.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, strong) UnityAppController* unityAppController;

@end

然后在.m中初始化unity

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"Jicheng5"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
//  [self.window makeKeyAndVisible];
  
  _unityAppController = [[UnityAppController alloc]init];//这里初始化unity
  [_unityAppController application:application didFinishLaunchingWithOptions:launchOptions];
//  self.window = _unityAppController.window;
  
  [self.window makeKeyAndVisible];
  
  return YES;
}
补充unity在app中其他状态的代码:

-(void)applicationWillResignActive:(UIApplication *)application{
  [_unityAppController applicationWillResignActive:application];
}

-(void)applicationDidEnterBackground:(UIApplication *)application{
  [_unityAppController applicationDidEnterBackground:application];
}

-(void)applicationWillEnterForeground:(UIApplication *)application{
  [_unityAppController applicationWillEnterForeground:application];
}

-(void)applicationDidBecomeActive:(UIApplication *)application{
  [_unityAppController applicationDidBecomeActive:application];
}

-(void)applicationWillTerminate:(UIApplication *)application{
  [_unityAppController applicationWillTerminate:application];
}

至此,我们所有必要条件都达成了,如果想看效果,可以在上面的application中,将RN的初始化注释掉,然后把
self.window = _unityAppController.window;

这样就可以看到unity页面了。


但是我们还是希望可以向组件一下显示它,怎么做呢?这里用到我之前的文章RN自定义显示view了,哈哈,没想到这么快就用到刚刚学会的知识了。

在xcode里面创建RCTUnityView 和 RCTUnityViewManager两个类:


接下来不多说了,直接看代码:

//
//  RCTUnityView.h
//  Jicheng5
//
//  Created by guojicheng on 16/9/20.
//  Copyright © 2016年 Facebook. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "UnityAppController.h"

@interface RCTUnityView : UIView

@property (nonatomic, strong) UIView* uView;

@end

//
//  RCTUnityView.m
//  Jicheng5
//
//  Created by guojicheng on 16/9/20.
//  Copyright © 2016年 Facebook. All rights reserved.
//

#import "RCTUnityView.h"

@implementation RCTUnityView

-(id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self){
    self.uView = (UIView*)GetAppController().unityView;
  }
  return self;
}

-(void)layoutSubviews
{
  [super layoutSubviews];
  [self.uView removeFromSuperview];
  self.uView.frame = self.bounds;
  [self insertSubview:self.uView atIndex:0];
  [self.uView setNeedsLayout];
}

@end

//
//  RCTUnityViewManager.h
//  Jicheng5
//
//  Created by guojicheng on 16/9/20.
//  Copyright © 2016年 Facebook. All rights reserved.
//

#import "RCTViewManager.h"

@interface RCTUnityViewManager : RCTViewManager

@end

//
//  RCTUnityViewManager.m
//  Jicheng5
//
//  Created by guojicheng on 16/9/20.
//  Copyright © 2016年 Facebook. All rights reserved.
//

#import "RCTUnityViewManager.h"
#import "RCTUIManager.h"
#import "RCTUnityView.h"

@implementation RCTUnityViewManager

RCT_EXPORT_MODULE();
@synthesize bridge = _bridge;

- (UIView *)view
{
  return [[RCTUnityView alloc] init];
}

- (dispatch_queue_t)methodQueue
{
  return dispatch_get_main_queue();
}

@end

好了,原生端已经准备完毕,在JS那边也要写一个组件,看代码:UnityView.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

'use strict'
import React, { Component } from 'react';
import { View } from 'react-native';
import { requireNativeComponent } from 'react-native';

class UnityView extends Component {
  setNativeProps(props){
    this.root.setNativeProps(props);
  }
  render() {
    return (
      <UnityViewNative
        {...this.props}
        style={[
          {backgroundColor: 'transparent'},
          this.props.style,
        ]} 
        ref={(r)=>{this.root = r}}
      />
    );
  }
}

UnityView.propTypes = {

};

const UnityViewNative = requireNativeComponent('RCTUnityView', UnityView);

export default UnityView;

至此组件做好咯,是不是很简单啊~哈哈哈哈。。

然后我们在index里面使用一下看看效果哈,有点小激动:

<span style="color:#ff0000;">import UnityView from './UnityView';</span>

class Jicheng5 extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.ios.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload,{'\n'}
          Cmd+D or shake for dev menu
        </Text>
        <span style="color:#ff0000;"><UnityView style={{width:300, height:200}}/></span>
      </View>
    );
  }
}

嘿嘿嘿,没错误,最后给大家看看运行效果,由于我导出的是Device SDK所以只能在真机上看:


立方体在自动旋转哦!~~


资料参考:AR学院-Unity导出的项目整合到已有的IOS项目中

将Unity页面添加到iOS APP中
unity项目整合嵌入iOS主工程

找了好几个,综合测试得到自己想要的了。。另外有英语好的,也可以看看他们最后参考的歪果仁写的教程。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏小败在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值