Flutter场景渲染插件scenekit_plugin的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter场景渲染插件scenekit_plugin的使用

scenekit_plugin

iOS平台上的一个插件,用于在SceneKit iOS中渲染3D模型。

目录

支持的平台

  • iOS 9.0+

特性

  • 3D地球
  • 可以在3D地球上添加小部件
  • 点击小部件
  • 在小部件中显示图片
  • 渲染场景释放

截图

| iOS | |

使用方法

初始化SceneKit视图

late ScenekitController scenekitController;

ScenekitView(
    onScenekitViewCreated: onScenekitViewCreated,
),

void onScenekitViewCreated(ScenekitController scenekitController) {
    this.scenekitController = scenekitController;
}

将地球放置到场景中

scenekitController.addWidgetToScene();

在地球上放置小部件

scenekitController.addWidgetToEarth(model:
    ScenekitWidgetModel(
        lat: 80,
        long: 5,
        name: "widgetNode1",
        assetName: 'assets/eagle.png',
        hexColor: 0x7FFF00,
        onWidgetTap: () async {
            await HapticFeedback.lightImpact();
            print("navigate to widgetNode1 !");
        },
    ),
)

在地球上放置多个小部件

scenekitController.addWidgetsToEarth(models: [
        ScenekitWidgetModel(
            lat: 80,
            long: 5,
            name: "widgetNode1",
            assetName: 'assets/eagle.png',
            hexColor: 0x7FFF00,
            onWidgetTap: () async {
                await HapticFeedback.lightImpact();
                print("navigate to widgetNode1 !");
            },
        ),
        ScenekitWidgetModel(
            lat: 43,
            long: -85,
            name: "widgetNode2",
            assetName: 'assets/eagle.png',
            hexColor: 0x7FFF00,
            onWidgetTap: () async {
                await HapticFeedback.lightImpact();
                print("navigate to widgetNode2 !");
            },
        ),
        ScenekitWidgetModel(
            lat: -19,
            long: 47,
            name: "widgetNode3",
            assetName: 'assets/eagle.png',
            hexColor: 0x7FFF00,
            onWidgetTap: () async {
                await HapticFeedback.lightImpact();
                print("navigate to widgetNode3 !");
            },
        ),
    ],
)

完整示例代码

以下是完整的示例代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:scenekit_plugin/controller/scenekit_plugin_controller_interface.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(home: ScenekitPage());
  }
}

class ScenekitPage extends StatefulWidget {
  const ScenekitPage({Key? key}) : super(key: key);

  [@override](/user/override)
  State<ScenekitPage> createState() => _ScenekitPageState();
}

class _ScenekitPageState extends State<ScenekitPage> {
  late ScenekitController scenekitController;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Row(children: [
          CupertinoButton(
            child: const Icon(Icons.public_sharp, color: Colors.white),
            onPressed: () async {
              await scenekitController.addEarthToScene(
                initialScale: 1.5,
                backgroundColor: 0xff1E3968,
              );
            },
          ),
          CupertinoButton(
            child: const Icon(Icons.place, color: Colors.white),
            onPressed: () async {
              await scenekitController.setWidgetsToEarth(models: [
                ScenekitWidgetModel(
                  key: "1",
                  lat: 50.83807146055582,
                  long: 156.87842152770136,
                  assetName: 'assets/eagle.png',
                  onWidgetTap: () async {
                    await HapticFeedback.lightImpact();
                    print("navigate to widgetNode1 !");
                  },
                ),
              ]);
            },
          ),
          CupertinoButton(
            child: const Icon(Icons.display_settings_outlined, color: Colors.white),
            onPressed: () async {
              await scenekitController.removeWidgets();
            },
          ),
        ]),
      ),
      body: _viewWithPlanet,
    );
  }

  Widget get _viewWithPlanet {
    return SizedBox(
      child: ScenekitView(
        isAllowedToInteract: true,
        onScenekitViewCreated: onScenekitViewCreated,
      ),
    );
  }

  void onScenekitViewCreated(ScenekitController scenekitController) async {
    this.scenekitController = scenekitController;
    final version = await scenekitController.getPlatformVersion();
    await scenekitController.addEarthToScene(
      initialScale: 0.62, // full
      // initialScale: 0.9, // 300
      backgroundColor: 0xff1E3968,
      // y: -0.45
    );
    print(version);
  }

  [@override](/user/override)
  void dispose() {
    //scenekitController.dispose();
    super.dispose();
  }
}

更多关于Flutter场景渲染插件scenekit_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter场景渲染插件scenekit_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用scenekit_plugin进行场景渲染的一个基本示例。请注意,此示例假设您已经有一个Flutter项目,并且已经正确地将scenekit_plugin添加到您的pubspec.yaml文件中。

首先,确保在pubspec.yaml中添加依赖项:

dependencies:
  flutter:
    sdk: flutter
  scenekit_plugin: ^最新版本号  # 请替换为实际可用的最新版本号

然后,运行flutter pub get来安装依赖项。

接下来,我们将在Flutter项目中创建一个简单的SceneKit场景。以下是一个完整的示例代码,展示如何使用scenekit_plugin

main.dart

import 'package:flutter/material.dart';
import 'package:scenekit_plugin/scenekit_plugin.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SceneKit Plugin Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SceneKitDemoPage(),
    );
  }
}

class SceneKitDemoPage extends StatefulWidget {
  @override
  _SceneKitDemoPageState createState() => _SceneKitDemoPageState();
}

class _SceneKitDemoPageState extends State<SceneKitDemoPage> {
  late SceneKitController _sceneKitController;

  @override
  void initState() {
    super.initState();
    _sceneKitController = SceneKitController(
      viewportSize: Size(800, 600), // 设置视口大小
      scene: _createScene(),
    )..initialize();
  }

  @override
  void dispose() {
    _sceneKitController.dispose();
    super.dispose();
  }

  SCNScene _createScene() {
    // 创建一个新的SceneKit场景
    final scene = SCNScene();

    // 创建一个立方体节点
    final cubeNode = SCNNode();
    final cubeGeometry = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.1);
    cubeNode.geometry = cubeGeometry;
    cubeNode.position = SCNVector3(0, 0, -5);

    // 创建一个光源节点
    final lightNode = SCNNode();
    final light = SCNOmniLight();
    light.color = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0);
    lightNode.light = light;
    lightNode.position = SCNVector3(0, 10, 10);

    // 将立方体节点和光源节点添加到场景中
    scene.rootNode.addChildNode(cubeNode);
    scene.rootNode.addChildNode(lightNode);

    return scene;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SceneKit Plugin Demo'),
      ),
      body: Center(
        child: SceneKitView(
          controller: _sceneKitController,
        ),
      ),
    );
  }
}

注意事项

  1. SCNScene, SCNNode, SCNBox, SCNOmniLight, UIColor, SCNVector3 等类在Flutter的scenekit_plugin中可能以不同的方式封装,具体取决于插件的实现。上面的代码使用了假设的API调用方式,实际使用时需要参考scenekit_plugin的文档。

  2. 由于scenekit_plugin是一个封装了SceneKit的Flutter插件,某些SceneKit的特性和API可能不完全可用或者有所不同。因此,在实际开发过程中,建议详细阅读scenekit_plugin的官方文档和示例代码。

  3. 如果scenekit_plugin提供了自定义的Widget或者不同的初始化方式,请按照插件的文档进行相应的调整。

  4. 确保您的开发环境支持SceneKit,并且已经正确配置了所有必要的依赖项和权限。

由于scenekit_plugin的具体API可能会随着版本更新而变化,因此在实际使用时,请参考最新的官方文档和示例代码。

回到顶部